ReactJS - prevState in the new useState React hook?
ReactjsReact HooksReactjs Problem Overview
I really like the new React hooks and I'm using them frequently for a project I'm working on. I'm coming across a situation where I want to use the prevState in the useState
hook, but I'm not really certain on how to do this.
I've tried something like this, but it fails to compile.
const [ someState, setSomeState ] = useState( new Map() )
setSomeState( prevState.someState.set( key, value ) )
(by the way, this is to map an array of checkboxes to keep track of the ones that are check marked)
I'm trying to follow this example here, but without using the setState
function.
Thanks for the help!
Reactjs Solutions
Solution 1 - Reactjs
For objects you can use the spread operator to use prevState
within your setState
call.
const [object, setObject] = useState({
firstKey: '',
secondKey: '',
});
setObject((prevState) => ({
...prevState,
secondKey: 'value',
}));
// object = {
// firstKey: '',
// secondKey: 'value',
// }
The snippet below show an example of using prevState
for setting the state of an object.
const {useState} = React;
const Example = ({title}) => {
const initialState = {
firstKey: 'empty',
secondKey: 'empty',
thirdKey: 'not empty',
}
const [object, setObject] = useState(initialState);
const withPrevState = () => {
setObject((prevState) => ({
...prevState,
secondKey: 'not empty',
}));
}
return (
<div>
<h5>Updates Second key to 'not empty'</h5>
<p>First key: {object.firstKey}</p>
<p>Second key: {object.secondKey}</p>
<p>Third key: {object.thirdKey}</p>
<button onClick={withPrevState}>
Update with prevState
</button>
<button onClick={() => {setObject({secondKey: 'not empty'})}}>
Update without prevState
</button>
<button onClick={() => {setObject(initialState)}}>
Reset
</button>
</div>
);
};
// Render it
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>
Solution 2 - Reactjs
In order to use Maps, you'll need to clone it before manipulating the values. Otherwise, it's mutating the original Map
and React doesn't handle mutatable state
.
const handleChange = useCallback(({ target: { name, checked } }) => {
setCheckbox(prevState => {
return new Map(prevState).set(name, checked);
});
}, []);
Updated Working Example:
Solution 3 - Reactjs
state updater
from useState
provides a callback pattern which returns you the previous state which you can use to update the current state
const [ someState, setSomeState ] = useState( new Map() )
setSomeState(prevState => prevState.set( key, value ) )
Solution 4 - Reactjs
You have already the previous state in the destructed variable: someState
so you can do:
const [ someState, setSomeState ] = useState( new Map() )
setSomeState( someState.set( key, value ) )
Solution 5 - Reactjs
use this
const [setSome, setSomeState] = useState({thing: 'loding', count: 1});
setSomeState(prev => ({...prev, count: prev.count + 1}));