gpt4 book ai didi

reactjs - redux-form 将对象动态注入(inject)到 Field Array `field` 属性中

转载 作者:行者123 更新时间:2023-12-02 21:18:18 24 4
gpt4 key购买 nike

我想要完成的是一个类似于redux form example中的动态FieldArray。但不同之处在于,我添加到列表中的每个对象都已经具有所有属性(我必须显示这些属性),但我需要从其中的其他两个属性中计算出一个属性。

看一下这个例子:

import React from 'react'
import { compose } from 'redux';
import { connect } from 'react-redux';
import { Field, FieldArray, reduxForm, formValueSelector } from 'redux-form'

const renderField = ({ input, label, type, meta: { touched, error } }) => (
<div>
<label>{label}</label>
<div>
<input {...input} type={type} placeholder={label}/>
{touched && error && <span>{error}</span>}
</div>
</div>
)

const renderSelect = (products) => (
<div>
<label>Select Product to Add</label>
<div>
<Field name="products" component="select">
<option></option>
{products.map(p => <option value={p.id}>{p.name}</option>)}
</Field>
</div>
</div>
);

const renderCompetences = ({ fields, meta: { touched, error, submitFailed }}) => {
return (
<div>
{/* <div>
<button type="button" onClick={() => fields.push({})}>Add Competence</button>
{(touched || submitFailed) && error && <span>{error}</span>}
</div> */}
<ul>
{fields.map((competence, index) =>
<li key={index}>
<h4>Competence #{index + 1}</h4>
<Field
name={`${competence}.singlePrice`}
type="number"
component={renderField}
label="Single Price"/>
<Field
name={`${competence}.standardQuantity`}
type="number"
component={renderField}
label="Standard Quantity"/>
<Field
name={`${competence}.totalPrice`}
type="number"
component={renderField}
label="Total Price"/>

<button
type="button"
onClick={() => fields.remove(index)}
style={{color: 'red'}}
>

</button>
</li>
)}
</ul>
</div>
);
}

const FieldArraysForm = (props) => {
const { handleSubmit, pristine, reset, submitting, products, productsValue } = props;

return (
<form onSubmit={handleSubmit}>
<Field name="recipientName" type="text" component={renderField} label="Recipient Name"/>
<FieldArray name="competences" component={renderCompetences} />
{renderSelect(products)}
<div>
<button type="submit" disabled={submitting}>Submit</button>
<button type="button" disabled={pristine || submitting} onClick={reset}>Clear Values</button>
</div>
</form>
)
}

const selector = formValueSelector('fieldArrays');

const mapStateToProps = (state) => {
const productsValue = selector(state, 'products');
return { productsValue };
};

export default compose(
connect(mapStateToProps),
reduxForm({
form: 'fieldArrays'
})
)(FieldArraysForm);

我应该在无序列表中显示我从选择中选择的产品,每次选择一个新对象时,我都应该将其添加到列表中。

在这里您可以看到产品数组的示例:

const products = [
{ id: '0', name: 'Product One', singlePrice: 101, standardQuantity: 1},
{ id: '1', name: 'Product Two', singlePrice: 39, standardQuantity: 6},
{ id: '2', name: 'Product Three', singlePrice: 85, standardQuantity: 4},
{ id: '3', name: 'Product Four', singlePrice: 1, standardQuantity: 20}
];

这是一个测试某些解决方案的工作示例: https://www.webpackbin.com/bins/-Kecgj77Gbxo_4am3WS1

非常感谢您提供的任何帮助!

最佳答案

这是我想出的解决方案:

import React from 'react'
import { compose } from 'redux';
import { connect } from 'react-redux';
import { Field, FieldArray, reduxForm, formValueSelector } from 'redux-form'

const renderField = ({ input, label, type, meta: { touched, error } }) => (
<div>
<label>{label}</label>
<div>
<input {...input} type={type} placeholder={label}/>
{touched && error && <span>{error}</span>}
</div>
</div>
)

const renderCalcField = ({ input, label, type, meta: { touched, error }, calc }) => (
<div>
<label>{label}</label>
<div>
<input {...input} type={type} placeholder={label} value={calc()} />
{touched && error && <span>{error}</span>}
</div>
</div>
)

const renderCompetences = ({ fields, meta: { touched, error, submitFailed }, products, productSelectValue }) => {
return (
<div>
<ul>
{fields.map((competence, index) =>
<li key={index}>
<h4>Competence #{index + 1}</h4>
<Field
name={`${competence}.singlePrice`}
type="number"
component={renderField}
label="Single Price"
onChange={() => {
const current = fields.get(index);
current.totalPrice = current.singlePrice * current.standardQuantity;
fields.remove(index);
fields.insert(index, current);
}}
/>
<Field
name={`${competence}.standardQuantity`}
type="number"
component={renderField}
label="Standard Quantity"
/>
<Field
name={`${competence}.totalPrice`}
type="number"
component={renderCalcField}
props={{calc: () => {
const current = fields.get(index);
return current.singlePrice * current.standardQuantity;
}}}
label="Total Price"
/>

<button
type="button"
onClick={() => fields.remove(index)}
style={{color: 'red'}}
>

</button>
</li>
)}
</ul>
<div>
<Field name="productSelect" component="select">
<option>Select product</option>
{products.map(p => <option value={p.id}>{p.name}</option>)}
</Field>
<button type="button" onClick={() => {
const selectedProduct = products.find(p => p.id === productSelectValue);
fields.push(selectedProduct);
}}>Add</button>
{(touched || submitFailed) && error && <span>{error}</span>}
</div>
</div>
);
}

const FieldArraysForm = (props) => {
const { handleSubmit, pristine, reset, submitting, products, productSelectValue } = props;

return (
<form onSubmit={handleSubmit}>
<Field name="recipientName" type="text" component={renderField} label="Recipient Name"/>
<FieldArray name="competences" component={renderCompetences} props={{products, productSelectValue}}/>
<div>
<button type="submit" disabled={submitting}>Submit</button>
<button type="button" disabled={pristine || submitting} onClick={reset}>Clear Values</button>
</div>
</form>
)
}

const selector = formValueSelector('fieldArrays');

const mapStateToProps = (state) => {
const productSelectValue = selector(state, 'productSelect');
return { productSelectValue };
};

export default compose(
connect(mapStateToProps),
reduxForm({
form: 'fieldArrays'
})
)(FieldArraysForm);

working here on webpackbin (有时它会出现加载问题,但它不依赖于我的示例)

关于reactjs - redux-form 将对象动态注入(inject)到 Field Array `field` 属性中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43117948/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com