我正在开发一个使用 React 和 Redux 作为前端 JavaScript 框架的 Web 应用程序。我在渲染 View 和更新 Redux 状态/存储值时遇到了一些问题。
我有一个更新 Redux 状态值的输入字段。这是我的文本字段的 onChange 事件处理程序。
_handleNameInput= (event) => {
this.props.updateField({
name: 'name',
value: event.target.value,
})
}
在 reducer 中,我正在像这样更新状态字段
case RESTAURANT_CATEGORY_UPDATE_FIELD: {
let freshState = { ...state };
_.set(freshState, action.payload.name, action.payload.value);
return freshState;
}
我正在使用 Lodash 来更新状态对象的字段。
这是我的默认状态
let defaultState = {
name: ''
}
当用户输入时,我会像这样在 View 上显示实时状态值。
<h1>Name is: {this.props.name}</h1>
上面的场景完全没问题。当我也在更改输入的值时,它正在显示实时更改。当我在状态下使用嵌套对象时,问题就开始了。我将 defaultState 更新为此。
let defaultState = {
form: {
name: '',
}
}
然后在回调中,我这样更新。
this.props.updateField({
name: 'form.name',
value: event.target.value,
})
它正在更新对象嵌套属性的 redux 状态/存储值。问题是当我像这样显示实时更改时
<h1>{this.props.form.name}</h1>
它没有更新/渲染 View 。我该如何解决?
最佳答案
当您通过 connect
函数将您的组件连接到 redux 时,您的组件表现为 PureComponent
。也就是说,它将对新 props 进行浅层检查,将它们与以前的 props 进行比较,以查看组件是否应该执行更新。
在第一个实例中,name
是一个顶级属性,它的变化被检测到,所以更新被执行。
在第二个实例中,form
是顶级属性,它没有改变,所以更新被阻止。
正如评论中所建议的,您可以使用 immer
来确保 form
对象被替换为具有更新后的 name
的新对象属性(property)。
import produce from "immer";
return produce(state, draft => {
_.set(draft, action.payload.name, action.payload.value);
});
在第二种情况下,它会有效地执行以下操作..
return {
...state,
form: {
...state.form,
name: action.payload.value
}
};
不过,我建议您重新考虑使用一个操作和缩减器来更新任意深度嵌套的字段,而是使用更具体的东西。
RESTAURANT_CATEGORY_UPDATE_FORM_FIELD
return {
...state,
form: {
...state.form,
[action.payload.name]: action.payload.value
}
};
或
return produce(state, draft => {
draft.form[action.payload.name] = action.payload.value;
});
关于javascript - 更新嵌套对象的字段而不是在 React Redux 中重新呈现 View (UI),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53974054/