最近在开发一个小项目,前端用react作为主要是框架。看了一下ant-design提供的组件,感觉很棒。使用form和redux集成的时候遇到了问题。
首先我们的表单需要初始化数据,根据ant的文档,如果用redux的话,建议是使用mapPropsToFields(props)方法。
Form组件的代码片段如下:
render() {
const insuranceProps = getFieldProps('insurance', {
initialValue: 0
});
const propertyTaxProps = getFieldProps('propertyTax', {
initialValue: 0
});
...
<Form.Item
{...formNumberItemLayout}
label="Insurance">
<InputNumber
{...insuranceProps}
min={0} />
</Form.Item>
<Form.Item
{...formNumberItemLayout}
label="Property Tax">
<InputNumber
{...propertyTaxProps}
min={0} />
</Form.Item>
....
<Form.Item
{...formNumberItemLayout}
label="Total Investment">
<Input
{...totalInvestmentProps}
readOnly={true}
type="text" />
</Form.Item>
....
export default Form.create({
onFieldsChange(props, field) {
props.onFieldsChange(field);
},
mapPropsToFields(props) {
return props.fields;
}
})(ProjectForm);
在form组件中,我们声明了insurance和propertyTax两个field,totalInvestment字段是根据前面两个字段计算所得。所以需要使用onFieldsChange方法来监听fields变化,实时的计算出totalInvestment的值。
相应的reducer代码:
const toProjectFields = (project) => {
const fields = {};
PROJECT_FIELDS_NAMES.forEach((name) => {
fields[name] = {
value: project[name]
};
});
return fields;
};
const getNewFormState = (state, payload) => {
const fields = {
...state,
...payload
};
const totalInvestment = COST_FIELDS_NAMES
.map((name) => {
if (fields[name]) {
return fields[name].value;
}
return 0;
})
.reduce((x, y) => (add(x, y)));
return {
...fields,
totalInvestment: {
value: totalInvestment
}
};
};
const form = (state = {}, action) => {
switch (action.type) {
case 'PROJECT_FORM_CHANGE':
return getNewFormState(state, action.payload);
case 'FETCH_PROJECT_SUCCESS':
const fields = toProjectFields(action.payload);
return getNewFormState(state, fields);
default:
return state;
}
};
export default combineReducers({
all,
form
});
这里PROJECT_FIELDS_NAMES的变量要列出所有project的属性,并将server端返回的对象转换成一个form fields对象,否则没有办法初始化form。
我这里的问题是,每一个form都需要写如此重复的代码吗?在Form组件中需要定义出field,还要在reducer中定义出字段名称。有没有redux的中间价可以帮助我们完成。
个人更喜欢redux-form的方式来处理form,但是redux-form和ant-design的form有很多重复的功能,而且redux-form也组件也没有ant-design的form丰富。