1 minute read

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!)

Readings

Why my setState doesn’t work

Leave a comment