React Note - 3. State
State?
State & Props are the core concept of the React framework which empower the modularity and efficiency of components.
React introduced React Hook in React 16.8 and it’s more like the only thing you should know rather than Class component nowadays.
<script type="text/bable">
const App = () => {
const [value, setValue] = React.useState(0);
return (
<div>
{ /* Wrap JS code (including comments) within a parenthesis */ }
<h2>{ value }</h2>
<button onClick={ () => setValue(25) }>
</button>
</div>
);
};
const root = document.getElementById("root");
ReactDOM.render(<App />, root);
</script>
Another Demonstration
const MinuteToHourConverter = () => {
const [minutes, setMinutes] = React.useState(0);
const [flipped, setFlipped] = React.useState(false);
const onChangeMinute = (e) => {
setMinutes(e.target.value);
};
const onChangeHour = (e) => {
setMinutes(e.target.value * 60);
};
const onReset = () => setMinutes(0);
const onFlip = () => setFlipped(curr => !curr);
return (
<div>
<div>
<label htmlFor="minute_input">Minutes</label>
<input value={minutes} id="minute_input" placeholder="Minutes" type="number" disabled={flipped === true}
onChange={onChangeMinute}/>
</div>
<div>
<label htmlFor="hour_input">Hours</label>
<input value={minutes / 60} id="hour_input" placeholder="Hours" type="number" disabled={flipped === false}
onChange={onChangeHour} />
</div>
<div>
<button onClick={onReset}>
Reset
</button>
<button onClick={onFlip}>
Flip
</button>
</div>
</div>
);
}
By using a state value minutes
we are controlling two input components at the same time.
State may be not updating when you’d expect
Can you guarantee the counter of below code is being correctly updated at console.log(counter)
?
const [counter, setCounter] = React.useState(0);
function foo() {
// You cannot guarantee the counter will be properly referenced and used at right timing
setCounter(counter + 1);
// What I am will be? 0? 1?
console.log(counter);
}
The function foo
means you are calling setCounter
with the state value.
The answer is: We can’t.
The updating state value will not be processed immediately(it will be blazing fast but still not an immediate). Because setState will be scheduled during reconcilation phase and you don’t know when is its turn.
Check the official document. reactjs : State Updates May be Asynchronous
The suggested way of using setCounter
would be
const [counter, setCounter] = React.useState(0);
function foo() {
setCounter((curr) => curr + 1);
// result will be guaranteed
console.log(counter);
}
Using arrow function ensures to take the current state internally and will update the state value accordingly.
And since the state variable is exposed externally, there is a chance that it is out of control from your scope (which you should not!)
Leave a comment