繁体   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