Mutating State From React's Usestate Hook
Solution 1:
You should never mutate state directly as it might not even cause a re-render if you update the state with the same object reference.
const { useState } = React;
functionApp() {
const [values, setValues] = useState({});
constdoSomething = (name, value) => {
values[name] = value;
setValues(values);
};
return (
<divonClick={() => doSomething(Math.random(), Math.random())}>
{JSON.stringify(values)}
</div>
);
}
ReactDOM.render(<App />, document.getElementById("root"));
<scriptsrc="https://unpkg.com/react@16/umd/react.development.js"></script><scriptsrc="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script><divid="root"></div>
You can give a function as first argument to setValues
just like you are used to in the class component setState
, and that function in turn will get the correct state as argument, and what is returned will be the new state.
constdoSomething = (name, value) => {
setValues(values => ({ ...values, [name]: value }))
}
const { useState } = React;
functionApp() {
const [values, setValues] = useState({});
constdoSomething = (name, value) => {
setValues(values => ({ ...values, [name]: value }));
};
return (
<divonClick={() => doSomething(Math.random(), Math.random())}>
{JSON.stringify(values)}
</div>
);
}
ReactDOM.render(<App />, document.getElementById("root"));
<scriptsrc="https://unpkg.com/react@16/umd/react.development.js"></script><scriptsrc="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script><divid="root"></div>
Solution 2:
Basically I would avoid mutating state in such way simply for the sake of purity.
However, I would argue that in this case it is perfectly fine. When you mutate a value in an inner level in the state it goes unnoticed by React. Only when calling setValues() with a new reference React notes to itself that a new render is pending.
const { useState } = React;
functionApp() {
const [values, setValues] = useState({ num: 0 });
consthandleClick = () => {
doSomething();
doSomething();
}
constdoSomething = () =>
setValues((values) => {
values.num += 1;
return { ...values };
});
return (
<divonClick={handleClick}>
{JSON.stringify(values)}
</div>
);
}
ReactDOM.render( < App / > , document.getElementById("root"));
<scriptsrc="https://unpkg.com/react@16/umd/react.development.js"></script><scriptsrc="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script><divid="root"></div>
(If anyone can provide a counter example I would love to see it).
Post a Comment for "Mutating State From React's Usestate Hook"