React Redux - 为什么我不能从 this.props 轻松设置 initialValues?
React Redux - Why can't I easily set initialValues from this.props?
所以我继承了一个项目,我需要在其中利用 FieldArrays
来创建项目的动态列表。它所在的 "form" 实际上并不在 <form>
中,因此我不得不将我的 FieldArrays
代码分割成它自己的组件,以便让 redux 神奇地使它成为 "work" 做我想让它做的事情,例如用数据预填充字段,能够轻松 add/remove 字段等
问题是我似乎无法使用更高层组件的 props 预填充组件,以便 redux FieldArray 可以拾取它,无论我尝试了什么。
这是我的代码:
renderFlooring({ fields, meta: { touched, error, submitFailed } }) {
return (
<div>
<div>
<div className={styles.flooringHeading}>
<h3> Site Specifications </h3>
<button type="button" className={styles.add} onClick={() => fields.push({})}>Add Square Footage</button>
</div>
{(touched || submitFailed) && error && <span>{error}</span>}
{fields.length === 0 &&
<p className={styles.noFlooring}>No square footage or flooring type has been added.</p>
}
</div>
<ul className={styles.sqFtList}>
{fields.map((flooring, index) =>
<li className={styles.card} key={index}>
<div className="page-form__block">
<p> Estimate the total area of work in square feet </p>
<Field name={`${flooring}.square_footage`} onChange={this.changeFlooringSquareFootage} component={TextField} hintText="Square Feet" />
</div>
<div className="page-form__block">
<p> Enter Floor Type </p>
<Field name={`${flooring}.flooring_type`} onChange={this.changeFlooringType} component={TextField} hintText="Floor Type (VCT, Carpet, Vinyle)" />
</div>
<button
type="button"
title="Remove"
className={styles.remove}
onClick={() => {
fields.remove(index);
this.props.removeFlooring(index);
}}>Remove</button>
</li>
)}
</ul>
</div>
);
}
render() {
return (
<FieldArray name="flooring" component={this.renderFlooring}/>
);
}
}
export default reduxForm({
form: 'manageSquareFootageForm',
initialValues: this.props.flooring
})(ManageSquareFootageForm);
导入此特定组件的组件如下所示:
<ManageSquareFootageForm
changeFlooringType={this.changeFlooringType}
changeFlooringSquareFootage={this.changeFlooringSquareFootage}
removeFlooring={this.removeFlooring}
flooring={this.props.flooring}
/>
我什至尝试在我的 <ManageSquareFootageForm>
上添加 initialValues
,但这最终导致我的 fields.push({})
功能停止工作。
我的数据如下所示:
[
{square_footage: "500", flooring_type: "carpet"},
{square_footage: "1000", flooring_type: "carpet"}
]
有什么我可以直接做的事情吗?
提前致谢!
发生这种情况是因为 reduxFrom HOC
不知道组件 props,你确实设置了 initialValues
from prop like
const FootableForm = reduxForm({
form: 'manageSquareFootageForm'
})(ManageSquareFootageForm);
export default connect((state, props) => ({
initialValues: props.flooring
}))(FootableForm)
但是,您的字段不是在初始加载时生成的,因此不会被填充,您宁愿使用 ReduxForm 中的 change
函数更新值。
const defaultValues = { square_footage: "500", flooring_type: "carpet" }
class FieldArraysForm extends React.Component {
componentDidUpdate(prevProps) {
const {flooring, change} = this.props;
const {flooring: prevflooring} = prevProps;
console.log(JSON.stringify(flooring));
// Do nothing if no flooring, or no change to flooring
if (!flooring || flooring === prevflooring) {
return;
}
if (!prevflooring || flooring.length > prevflooring.length) {
change('flooring', flooring.slice(0, flooring.length - 1).concat(defaultValues));
}
}
render() {
const { handleSubmit, pristine, reset, submitting } = this.props;
return (
<form onSubmit={handleSubmit}>
<FieldArray name="flooring" component={renderFlooring} />
</form>
);
}
};
const FieldForm = reduxForm({
form: 'fieldArrays', // a unique identifier for this form
validate,
})(FieldArraysForm);
export default connect(state => ({
flooring: (getFormValues('fieldArrays')(state) || {}).flooring
}))(FieldForm);
检查工作codeSandbox
所以我继承了一个项目,我需要在其中利用 FieldArrays
来创建项目的动态列表。它所在的 "form" 实际上并不在 <form>
中,因此我不得不将我的 FieldArrays
代码分割成它自己的组件,以便让 redux 神奇地使它成为 "work" 做我想让它做的事情,例如用数据预填充字段,能够轻松 add/remove 字段等
问题是我似乎无法使用更高层组件的 props 预填充组件,以便 redux FieldArray 可以拾取它,无论我尝试了什么。
这是我的代码:
renderFlooring({ fields, meta: { touched, error, submitFailed } }) {
return (
<div>
<div>
<div className={styles.flooringHeading}>
<h3> Site Specifications </h3>
<button type="button" className={styles.add} onClick={() => fields.push({})}>Add Square Footage</button>
</div>
{(touched || submitFailed) && error && <span>{error}</span>}
{fields.length === 0 &&
<p className={styles.noFlooring}>No square footage or flooring type has been added.</p>
}
</div>
<ul className={styles.sqFtList}>
{fields.map((flooring, index) =>
<li className={styles.card} key={index}>
<div className="page-form__block">
<p> Estimate the total area of work in square feet </p>
<Field name={`${flooring}.square_footage`} onChange={this.changeFlooringSquareFootage} component={TextField} hintText="Square Feet" />
</div>
<div className="page-form__block">
<p> Enter Floor Type </p>
<Field name={`${flooring}.flooring_type`} onChange={this.changeFlooringType} component={TextField} hintText="Floor Type (VCT, Carpet, Vinyle)" />
</div>
<button
type="button"
title="Remove"
className={styles.remove}
onClick={() => {
fields.remove(index);
this.props.removeFlooring(index);
}}>Remove</button>
</li>
)}
</ul>
</div>
);
}
render() {
return (
<FieldArray name="flooring" component={this.renderFlooring}/>
);
}
}
export default reduxForm({
form: 'manageSquareFootageForm',
initialValues: this.props.flooring
})(ManageSquareFootageForm);
导入此特定组件的组件如下所示:
<ManageSquareFootageForm
changeFlooringType={this.changeFlooringType}
changeFlooringSquareFootage={this.changeFlooringSquareFootage}
removeFlooring={this.removeFlooring}
flooring={this.props.flooring}
/>
我什至尝试在我的 <ManageSquareFootageForm>
上添加 initialValues
,但这最终导致我的 fields.push({})
功能停止工作。
我的数据如下所示:
[
{square_footage: "500", flooring_type: "carpet"},
{square_footage: "1000", flooring_type: "carpet"}
]
有什么我可以直接做的事情吗?
提前致谢!
发生这种情况是因为 reduxFrom HOC
不知道组件 props,你确实设置了 initialValues
from prop like
const FootableForm = reduxForm({
form: 'manageSquareFootageForm'
})(ManageSquareFootageForm);
export default connect((state, props) => ({
initialValues: props.flooring
}))(FootableForm)
但是,您的字段不是在初始加载时生成的,因此不会被填充,您宁愿使用 ReduxForm 中的 change
函数更新值。
const defaultValues = { square_footage: "500", flooring_type: "carpet" }
class FieldArraysForm extends React.Component {
componentDidUpdate(prevProps) {
const {flooring, change} = this.props;
const {flooring: prevflooring} = prevProps;
console.log(JSON.stringify(flooring));
// Do nothing if no flooring, or no change to flooring
if (!flooring || flooring === prevflooring) {
return;
}
if (!prevflooring || flooring.length > prevflooring.length) {
change('flooring', flooring.slice(0, flooring.length - 1).concat(defaultValues));
}
}
render() {
const { handleSubmit, pristine, reset, submitting } = this.props;
return (
<form onSubmit={handleSubmit}>
<FieldArray name="flooring" component={renderFlooring} />
</form>
);
}
};
const FieldForm = reduxForm({
form: 'fieldArrays', // a unique identifier for this form
validate,
})(FieldArraysForm);
export default connect(state => ({
flooring: (getFormValues('fieldArrays')(state) || {}).flooring
}))(FieldForm);
检查工作codeSandbox