我是反应原生,redux和saga的新手,并且遇到了一个我无法找到解决方案的用例。我理解如何将状态映射到属性并在action,reducer和saga之间传递状态。到目前为止,这对我来说很有意义。事情似乎变得有点冒险。我有一个表单,在任何给定的时间需要可变数量的表单字段,具体取决于从数据库返回的内容。
作为一个例子,让我们说我有这样的结构:
{
name: ‘’,
vehicleMake: ‘’,
vehicleModel: ‘’,
carLotCity: ‘’,
carLotState: ‘’,
carLotZipCode: ‘’,
localPartsManufacturers: [{name: ‘’, address: ‘’, zipCode}]
}
从name到carLotZipCode的所有内容只需要一个文本字段,但是,localPartsManufacturers数组可以表示任意数量的对象,每个对象需要每个对象拥有自己的一组文本字段。如果将字段映射到状态并将状态映射到属性,我将如何使用redux来解释这个问题?我对如何开始这个场景很困惑。我理解在修复字段时如何投影映射。
答案 0 :(得分:3)
我会保留数据,因为它来自后端。这样你就可以避免它的正常化。我认为在渲染字段时我们必须更聪明。以下是我建议的内容:
function onTextFieldChange(name, index) {
// either name = `name`, `vehicleMake`, ...
// or
// name = `localPartsManufacturers` and `index` = 0
}
function createTextField(name, index) {
return <input
type='text'
name={ name }
onChange={ () => onTextFieldChange(name, index) } />;
}
function Form({ fields }) {
return (
<div>
{
Object.keys(fields).reduce((allFields, fieldName) => {
const field = fields[fieldName];
if (Array.isArray(field)) {
allFields = allFields.concat(field.map(createTextField));
} else {
allFields.push(createTextField(fieldName));
}
return allFields;
}, [])
}
</div>
);
}
Form
会在商店中收到您拥有的所有数据。然后我们检查该字段是否为数组。如果它是一个数组,我们遍历内部的字段并生成与其他属性createTextField
相同的输入。这里棘手的部分是如何更新商店中的数据。请注意,我们在更改文本字段数据时传递index
。在reducer中我们必须写出类似的东西:
case FIELD_UPDATED:
const { name, index, value } = event.payload;
if (typeof index !== 'undefined') {
state[name][index] = value;
} else {
state[name] = value;
}
return state;
答案 1 :(得分:2)
没有任何东西阻止您在Redux中保留列表,地图,集合或任何其他对象。
唯一剩下的就是如何将状态映射到道具,以及如何使用它们。您不是将单个元素从集合映射到prop,而是将整个集合映射到单个prop,然后在render方法中迭代集合。
在操作中,您可以传回新的集合,该集合由构成部件列表的表单字段组成。然后,您的reducer将替换该集合本身。
或者,在更改零件集合中的元素时,您可以发送具有其id的操作,在reducer中的集合中找到它并替换已更改的元素/添加新元素/删除已删除的元素。 / p>