簡體   English   中英

從 React 的 useState 鈎子改變狀態

[英]Mutating state from React's useState hook

是嗎,為什么從 React 的新 useState 鈎子改變狀態是個壞主意? 我沒有找到有關該主題的信息。

考慮以下代碼:

const [values, setValues] = useState({})

// doSomething can be called once, or multiple times per render

const doSomething = (name, value) => {
  values[name] = value
  setValues({ ...values })
}

注意值的變化。 由於每次渲染可以多次調用 doSomething,由於 setState 的異步屬性,這樣做將不起作用:

const doSomething = (name, value) => {
  setValues({ ...values, [name]: value })
}

在這種情況下,直接改變值的方法是否正確?

切勿直接更改狀態,因為如果使用相同的對象引用更新狀態,甚至可能不會導致重新渲染。

 const { useState } = React; function App() { const [values, setValues] = useState({}); const doSomething = (name, value) => { values[name] = value; setValues(values); }; return ( <div onClick={() => doSomething(Math.random(), Math.random())}> {JSON.stringify(values)} </div> ); } ReactDOM.render(<App />, document.getElementById("root")); 
 <script src="https://unpkg.com/react@16/umd/react.development.js"></script> <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script> <div id="root"></div> 

您可以將函數作為setValues第一個參數,就像您在類組件setState所習慣的那樣,然后該函數將獲得正確的狀態作為參數,返回的將是新狀態。

const doSomething = (name, value) => {
  setValues(values => ({ ...values, [name]: value }))
}

 const { useState } = React; function App() { const [values, setValues] = useState({}); const doSomething = (name, value) => { setValues(values => ({ ...values, [name]: value })); }; return ( <div onClick={() => doSomething(Math.random(), Math.random())}> {JSON.stringify(values)} </div> ); } ReactDOM.render(<App />, document.getElementById("root")); 
 <script src="https://unpkg.com/react@16/umd/react.development.js"></script> <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script> <div id="root"></div> 

基本上我會避免以這種方式改變狀態,只是為了純度。

但是,我認為在這種情況下它完全沒問題。 當你在 state 的內部級別改變一個值時,它不會被 React 注意到。 只有在使用新的引用調用 setValues() 時,React 才會注意到新的渲染正在掛起。

 const { useState } = React; function App() { const [values, setValues] = useState({ num: 0 }); const handleClick = () => { doSomething(); doSomething(); } const doSomething = () => setValues((values) => { values.num += 1; return { ...values }; }); return ( <div onClick={handleClick}> {JSON.stringify(values)} </div> ); } ReactDOM.render( < App / > , document.getElementById("root"));
 <script src="https://unpkg.com/react@16/umd/react.development.js"></script> <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script> <div id="root"></div>

(如果有人可以提供一個反例,我很樂意看到它)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM