繁体   English   中英

在 useReducer 中是否需要使用扩展运算符?

[英]Is it necessary to use the spread operator in useReducer?

编辑:在检查了 Brian 的答案后,我发现即使在第二个示例中,删除...state也会导致与第一个示例相同的行为,所以这个问题是错误的。 我不确定是什么让我看到了错误的行为,并对造成的任何不便表示歉意。 布赖恩的回答是对用法的一个很好的解释。

比较以下 2 个代码片段,它们通过使用initialState一次更新 2 个状态来做同样的事情,除了一个使用useState而另一个使用useReducer

  1. useState

 const {useState} = React; const initialState = { name: 'John', age: 20 }; const Example = () => { const [state, setState] = useState(initialState); const handleName = () => { setState({...state, name: 'Tom'}); } const handleAge = () => { setState({...state, age: 30}); } return ( <div> <p>{state.name}</p> <p>{state.age}</p> <button onClick={handleName}> Click to change name </button> <button onClick={handleAge}> Click to change age </button> </div> ); }; ReactDOM.render( <Example />, document.getElementById("react") );
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script> <div id="react"></div>

  1. useReducer

 const {useReducer} = React; const initialState = { name: 'Tom', age: 30 } const reducer = (state, action) => { switch (action.type) { case 'name': return { ...state, name: 'John' } case 'age': return { ...state, age: 25 } default: return state } } const Example = () => { const [state, dispatch] = useReducer(reducer, initialState); return ( <div> <p>Name: {state.name}</p> <p>Age: {state.age}</p> <button onClick={() => dispatch({ type: 'name' })}>Click to update name</button> <button onClick={() => dispatch({ type: 'age' })}>Click to update age</button> </div> ) }; ReactDOM.render( <Example />, document.getElementById("react") );
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script> <div id="react"></div>

如果在第一个示例中删除...state ,它将状态设置为单个键/值对,因此不再有效。 我期待在第二个例子中发生同样的事情,但事实并非如此。 第二个示例在删除扩展运算符后运行良好。

对于第二个示例,我有 3 个问题:

  1. 点差运算符的用途是什么?
  2. 为什么删除扩展运算符后它仍然有效?
  3. 如果它在没有扩展运算符的情况下运行良好,那是否意味着在第二个示例中不需要扩展运算符?

我明白,这是一个非常类似的问题这一个,但我无论如何给一个答案,希望能阻止未来的读者从得到不正确的信息。

useStateuseReducer都不做任何先前值的合并。 在状态更新期间(在setState调用中或在 reducer 函数定义中),任何保留先前状态值都是您的责任。

您可以在下面修改后的代码中清楚地看到这一点。 我所做的改变就是从每个开关盒中删除...state

 const {useReducer} = React; const initialState = { name: 'Tom', age: 30 } const reducer = (state, action) => { switch (action.type) { case 'name': return { name: 'John' } case 'age': return { age: 25 } default: return state } } const Example = () => { const [state, dispatch] = useReducer(reducer, initialState); return ( <div> <p>Name: {state.name}</p> <p>Age: {state.age}</p> <button onClick={() => dispatch({ type: 'name' })}>Click to update name</button> <button onClick={() => dispatch({ type: 'age' })}>Click to update age</button> </div> ) }; ReactDOM.render( <Example />, document.getElementById("react") );
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script> <div id="react"></div>

为此目的频繁使用扩展运算符的原因是它是将所有未更改的值放入新对象的最不乏味的方法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM