背景:
我已经开始使用React构建应用程序。整个用户界面基于一个大对象调查,有几个(15-20)组件更新该对象的部分。调查对象通过单个服务器调用获取,对象保存,另一个调用服务器。每个组件中进行的所有元素更新都是为了更新大型Survey对象的一部分。
我打算使用Redux为每个元素/字段进行状态更新,因为它是清理和中央状态管理。
为了做到这一点,我需要绑定' onChange'所有元素的事件处理程序。例如,每次文本框值发生更改时,都会触发操作并且相应的缩减器会截取并更新状态。
因此,对于组件中的以下元素,
<input
className="form-control form-control-lg"
type="text"
placeholder="Username"
value={this.props.username}
onChange={this.changeUsername} />
触发以下操作
onChangeUsername(){
dispatch({ type: UPDATE_FIELD_AUTH, key: 'username', value }),
...
}
减速器更新状态......
(survey = {}, action) => {
switch (action.type) {
case UPDATE_FIELD_AUTH:
return { ...survey , [action.key]: action.value };
default:
return state;
}
简而言之,我们正在执行以下操作来更新单个字段的状态: 元素事件处理程序 - &gt;调度Redux动作 - &gt; Redux reducer更新字段
Survey
-> Name
-> Description
-> Section
->Name
->Number
->Question
->Name
->Type
->Option
->Name
->Type
->Value
问题 应用程序中可能有100个这样的字段,可能会从两个不同的组件更新相同的字段。这是要遵循的模型吗?
答案 0 :(得分:1)
我的直觉是,您希望将单个调度程序用于多个onChange
事件
有组件:
const inputView = props => (
<input
type="text"
placeholder="Username"
value={this.props.username}
onChange={e => { this.props.onChange('username', e.target.value) }}
/>
);
有调度员:
const mapDispatchToProps = dispatch => ({
onChange: (key, value) => dispatch({
type: actionTypes.UPDATE_FIELD,
key,
value
}),
});
export default connect(mapStateToProps, mapDispatchToProps)(inputView);
还有减速器:
const reducer = (state = initState, action) => {
switch (action.type) {
case actionTypes.UPDATE_FIELD:
return {
...state,
[action.key]: action.value,
};
default:
return state;
}
};
效率这么高吗?
绝对是的。
由于多个输入通过相同的条件,因此switch语句并不复杂。
此外,如果您有更多组件/部分,多个缩减器始终是一个选项。
根据React doc,即使setState
也不会立即更新,但新道具将始终立即触发渲染功能。所以这个中央存储实现实际上比在每个组件中保持状态更好,你不必担心链接状态可能会出现异步或导致副作用。
<强>更新强>
嵌套状态的更新未在原始问题中显示,并且问题中的input
设置与数据结构不匹配。
鉴于这样的状态。假设用户无法删除问题,则每个部分将按顺序呈现
跟踪索引很容易,因为我们不想在每个onChange
事件中搜索状态。
const state = {
Survey: {
Name: '',
Description: '',
Section: [
{
Name: '',
Number: 0,
Question: [
{
Name: '',
Type: '',
Value: '1', // input value should be in this level
Option: [ // handle input type="select"
{ value: '1', displayValue: '1' },
{ value: '2', displayValue: '2' },
],
},
],
},
],
},
};
我们的想法是在最低级别创建一个深层副本。
const reducer = (state = initState, action) => {
switch (action.type) {
case actionTypes.UPDATE_FIELD:
const survey = { ...state.Survey };
const section = { ...survey.Section[action.sectionIdx] };
const question = { ...section.Qustion[action.questionIdx] };
question.Value = action.value;
section[sectionIdx].Qustion = question;
survey.Section = section;
return {
...survey,
};
default:
return state;
}
};
的官方链接