簡體   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