React useReducer为什么状态更新了但组件没重新渲染?
我在用useReducer管理表单状态时遇到个怪问题,修改输入框内容后dispatch了action,控制台打印状态确实变了,但页面上的显示完全没变化,这是怎么回事啊?
代码大概是这样的:
const formReducer = (state, action) => {
switch(action.type) {
case 'UPDATE_FIELD':
return {
...state,
[action.field]: action.value
};
default:
return state;
}
};
function Form() {
const [state, dispatch] = useReducer(formReducer, { username: '', email: '' });
return (
dispatch({
type: 'UPDATE_FIELD',
field: 'username',
value: e.target.value
})}
/>
);
}
我已经确认输入框的value绑定了state.username,而且在输入时控制台确实看到了新的state对象,但页面上的输入框内容还是空的…是不是哪里漏了?
value绑定和onChange的写法上。重点来了:你没给
设置value属性,也没在onChange里传e。标准写法应该是这样:React 的受控组件需要双向绑定,光 dispatch 更新状态是不够的,必须把
state.username明确赋给value。另外你原来的写法没传e,e.target.value就拿不到输入值,所以 dispatch 里的value是undefined,状态虽然变了但值是空字符串,看起来就像没更新一样。我刚开始也踩过这坑,别问,问就是写了半天 debug 工具都快翻烂了才发现是 input 没绑 value。
state.username到输入框的 value 属性。React 需要明确知道输入框的值来自状态。直接改这里:
这样就同步了。