使用useReducer控制表单时,是否需在每个action中传递旧state?
...state的作用与必要性解答 你的表单包含两个输入框:
- username(
type="text") - email(
type="email")
你通过.json文件做验证,仅当用户名不存在时提交按钮可点击,现在针对你困惑的...state使用问题,给出明确解释:
为什么要用...state?
在React的useReducer(或Redux)机制中,reducer是纯函数,必须返回全新的状态对象,绝对不能直接修改原state。React依赖状态的引用变化触发组件重渲染,如果直接修改原state,React检测不到状态变更,就不会更新UI,这就是你之前遇到bug的核心原因。
...state是ES6对象扩展运算符,作用是完整复制原state的所有属性,之后你可以在这个复制出的新对象上修改需要更新的字段。这样既保留了原状态中无需改动的部分(比如修改用户名时,邮箱的状态不会丢失),又创建了全新的状态对象,保证状态的不可变性,让React能正确识别状态变化并更新界面。
是否必须始终使用?
是的,除了default分支(初始化状态),其他所有case都必须使用...state。
因为reducer返回的状态必须包含所有状态属性,不能只返回部分字段。比如你在USERNAME_INPUT分支如果不用...state,返回的对象就只有usernameValue,emailValue、usernameIsValid等其他状态字段都会丢失,导致后续逻辑(比如EMAIL_INPUT里判断formIsValid时用到state.usernameIsValid)出错,引发各种异常。
看你的代码,比如API_RETURN_USERNAME分支修改了多个状态字段,但通过...state保留了原状态中未提及的属性;EMAIL_INPUT里用到state.usernameIsValid,这个值正是之前通过...state保留下来的,要是没加...state,这个值就会丢失,导致formIsValid计算错误。
补充说明
你的default分支是初始化状态,直接返回完整的初始对象即可,不需要...state——因为此时还没有可复制的原状态。
内容的提问来源于stack exchange,提问作者PeterO

