0

I might be having one of those days but I am updating state in boolean and numbers, but when I click on the values the old value appears first, and no the value of the button does not depend on the old value, do you still have to use prev value even for boolean, if so how and why?

https://stackblitz.com/edit/react-xj8gka?file=src%2FApp.js

Minimal example in the stackblitz too:

import React, {useState} from "react";
import "./style.css";


export default function App() {

  const [value, setValue] = useState(1)
  const [boolean, setBoolean] = useState(false)

  return (
    <div>

<button onClick={() => {setValue(() => 1)
        console.log(value)
        }}>Value 1</button>

<button onClick={() => {setValue(() => 2)
        console.log(value)
        }}>Value 2</button>
<p>Booleans</p>

<button onClick={() => {setBoolean(() => true)
        console.log(boolean)
        }}>True</button>

<button onClick={() => {setBoolean(() => false)
        console.log(boolean)
        }}>False</button>
      
    </div>
  );
}
Sole
  • 3,100
  • 14
  • 58
  • 112
  • 4
    Does this answer your question? [The useState set method is not reflecting a change immediately](https://stackoverflow.com/questions/54069253/the-usestate-set-method-is-not-reflecting-a-change-immediately) - you can't use `console.log` after `setState` because it won't work, the updated values will be available in the next render cycle, put `console.log(value, boolean)` in the body of the component and you will see that it works fine – Konrad Jan 06 '23 at 12:13

3 Answers3

1

you only need to pass a callback function to the setter function setBoolean incase you want to use the old value like this example setBoolean((prevBool) => !prevBool) // toggling the old bool value

while if you want to set a definite value that doesn't depend on the old one you just need to put it directly like this setBoolean(true) i don't see why you would need a callback function to return true

also as Konrad menitioned console.log(value) or console.log(bool) will get you the prev value first then on the next cycle render it will get you the updated value better to put console.log on the body of the component before the return of the jsx

Ahmad ghoneim
  • 844
  • 7
  • 13
-1

As in the comment said useState hook is asynchronous, it would be easier if you render your value on the component, if you simply want the right result to display on the console.log in your example using useState hooks i think you would need to use the sideeffect from useEffect and call the log when you need at the right moment :

import React, { useState, useEffect } from 'react';
import './style.css';

    export default function App() {
      const [value, setValue] = useState(1);
      const [boolean, setBoolean] = useState(false);
    
      function displayValue(btnValue) {
        if (value === btnValue) {
          console.log(value);
        }
      }
      function displayboolean(btnValue) {
        if (boolean === btnValue) {
          console.log(boolean);
        }
      }
    
      useEffect(() => {
        console.log(value);
      }, [value]);
      useEffect(() => {
        console.log(boolean);
      }, [boolean]);
    
      return (
        <div>
          <button
            onClick={() => {
              setValue(1);
              displayValue(1);
            }}
          >
            Value 1
          </button>
    
          <button
            onClick={() => {
              setValue(2);
              displayValue(2);
            }}
          >
            Value 2
          </button>
          <p>Booleans</p>
    
          <button
            onClick={() => {
              setBoolean(true);
              displayboolean(true);
            }}
          >
            True
          </button>
    
          <button
            onClick={() => {
              setBoolean(false);
              displayboolean(false);
            }}
          >
            False
          </button>
        </div>
      );
    }

But the value is already successfully updated if you render in your example a third button with the state value.

<button>value: {value}</button> 
ShueiYang
  • 648
  • 1
  • 3
  • 7
-2

Yes it is recommended to use a function with the the previous value as its first argument. This way, if you change the state twice inside the same component as you did above, the state updating function will have the most recent version of the state.

If you don't use the previous value, your state will only be updated if the component is re-rendered.

Data Moose
  • 367
  • 1
  • 6
  • There is no need to use the current value as a function parameter if you don't depend on the current value. Simply setting a value can be done without a function even, e.g. `setBoolean(false)` or `setValue(2)`. For the question above, it wouldn't matter. The `console.log` is using the state value and that is only updated in the next render, regardless how you store it in the setter. – Matthias S Jan 06 '23 at 12:21
  • if you look at the stackblitz example, it does not update on click as expected even using `setValue(2)` – Sole Jan 06 '23 at 12:25