我有一个根据用户保存的信息进行填充的表单,用户可以随时更改这些信息。
有关其结构的简单示例是:
componentWillMount() {
const { user, getProfile } = this.props;
if (user.profileId) {
getProfile(user.profileId); // this is a redux action that fetch for user profile data updating the props.
}
}
onChangeValue(e) {
const { updateProfileField } = this.props; // this is a redux action to update a single input
const { id, value } = e.target;
updateProfileField(id, value);
}
输入看起来像这样:
<InputField id="screenName" type="text" value={profile.screenName} onChangeValue={this.onChangeValue} placeholder="Your username" />
InputField
组件如下:
class InputField extends Component {
constructor(props) {
super(props);
this.state = {
value: props.value,
};
this.onChangeValue = this.onChangeValue.bind(this);
}
onChangeValue(value) {
this.props.onChangeValue(value);
}
render() {
const {
id, type, parent,
} = this.props;
return (
<input
id={id}
parent-id={parent}
className="form-control"
type={type}
name={id}
value={this.state.value}
onChange={this.onChangeValue}
/>
);
}
}
用于处理updateProfileField
的Redux动作是:
export function updateProfileField(field, value) {
const payload = { field, value };
return dispatch => dispatch({payload, type: types.UPDATE_PROFILE_FIELD});
}
最后的减速器:
const initialState = {
data: {}, // Here are stored the profile information like `screenName`
...
};
export default (state = initialState, action) => {
const { type, payload } = action;
switch (type) {
...
case types.UPDATE_PROFILE_FIELD:
// Here my attempts to update the input value
return {
...state,
data: { ...state.data, [payload.field]: payload.value },
};
// Immutability helper
// return update(state, {
// data: { [payload.field]: { $set: payload.value } },
// });
// return Object.assign({}, state.data, {
// [payload.field]: payload.value,
// });
}
}
重点是,只要加载页面并开始在表单中键入信息,一切就可以正常工作。
如果我更改了代码中的某些内容,它将使用HMR
自动重新加载,我可以在输入中看到之前键入的信息,但是如果我尝试更新该信息,它将不再起作用...
我可以看到"state"
仅更新了输入的最后一个字母,并且UI似乎冻结了。 (即:输入值为:'foo',我键入:'bar',结果为:foob,fooa,foor ...,并且它不会反映在UI中。)
我想我在这里做错了...