从 React 的使用中变异状态状态钩子



是吗,为什么从 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>

基本上,我会避免以这种方式改变状态只是为了纯粹。

但是,我认为在这种情况下完全没问题。当你在内部级别中改变一个值时,它不会被 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>

(如果有人可以提供反例,我很想看到它)。

相关内容

  • 没有找到相关文章

最新更新