我渲染形式一组动态文本元素。我已经使用normalizr principles规范了我的状态,所以有一个elementIds数组和一个包含elementIds引用的元素属性的对象(请参阅下面代码示例中的初始状态)。
目的
我的目的是简单地对两个渲染的元素是可编辑的。我使用onChange回调函数成功地将一个动作CHANGE_ELEMENT_VALUE分配给我的商店,在reducer中可以使用action.id(引用已更改元素的id)和action.value(新值)(请参阅下面的代码)。
问题
我的问题是,当我键入文本字段没有发生变化,即使我可以看到使用devtools Redux的扩展状态改变。我的理解是,反应并不能识别状态变化,因为变化是深入的状态,而且我没有成功创建一个新的状态对象,我可能以某种方式引用旧的实例。
减速码
下面是我的拙劣企图迫使一个新的状态对象。我假设它不工作,因为我的组件没有被重新渲染。它也显得非常不雅。
let initialState = {
isLoading: false,
data: {
elementIds: ['name', 'email'],
elements: {
'name': {'id': 'name', 'value':'ben'},
'email': {'id':'email', 'value':'[email protected]'},
},
},
error: false
}
function formReducer(state = initialState, action = null) {
switch(action.type) {
case types.CHANGE_ELEMENT_VALUE:
let newData = Object.assign(state.data)
newData.elements[action.id].value = action.value
return {...state, data: newData}
default:
return state;
}
}
export default formReducer;
我注意到的第一个问题是您滥用Object.assign。如果你测试它,你可以看到'newData === state.data',这是因为第一个参数是目标。一般来说,你总是会有这个深层次克隆对象的“问题”(如果结构是动态的,它会变得更丑),所以下面的答案可能对你有用。我个人使用https://www.npmjs.com/package/icepick –