🌐
GitHub
github.com › facebook › react › issues › 22272
Feature Request - useEffect - Provide boolean values on whether dependency has changed. · Issue #22272 · facebook/react
September 8, 2021 - I can imagine that this could result in some performance decrease but we could consider making a dedicated version of useEffect like useObservableEffect or something like that (I'm not great at naming so i'm sure the community can come up with a better name :D) Currently we use a workaround which requires using a ref to hold the previous values and comparing them inside the useEffect.
Author   yamarco
Discussions

reactjs - useState with boolean value in react - Stack Overflow
This is the expected behavior. You may want to use useEffect to access the latest value. Here is a thread discussing the same issue: useState set method not reflecting change immediately More on stackoverflow.com
🌐 stackoverflow.com
Hook is not triggered when boolean property changed on nested object.
use-deep-compare-effect version:1.3.0 node version: 12.9.1 npm (or yarn) version: 6.4.1 What you did: Passed an object (nested) as prop to a functional component What happened: One of the nested pr... More on github.com
🌐 github.com
7
November 21, 2019
why boolean variable is passed to useState() is always false? React hooks
Bring the best of human thought and AI automation together at your work. Explore Stack Internal ... I have a simple functional component and would like to initialize the state with a boolean, depending on the condition. More on stackoverflow.com
🌐 stackoverflow.com
How to check if state default boolean false is changing to true with React Hook useEffect
Your boolean.current value will never be changed as it's useEffect callback behaves as contructor function which will run only once as we have empty dependency inside it. More on stackoverflow.com
🌐 stackoverflow.com
🌐
Reddit
reddit.com › r/reactjs › should i use useeffect when its dependency is true/false and is directly from props?
r/reactjs on Reddit: Should I use useEffect when its dependency is true/false and is directly from props?
May 12, 2022 -

Can’t we just use the prop value directly instead of wrapping it in a useEffect?

Say,

Component = ({bool}) => {

If (bool) playSound()

return … }

Versus:

UseEffect(() => if(bool) playSound(), [bool])

These two cases have same behavior.

Update: It’s better to use useEffect, which only fires the side effect when the dependency changes when a component re-renders. It guards against incorrectly triggering the side effect if the dependency did not change value upon component re-render.

🌐
Lightrun
lightrun.com › answers › facebook-react-feature-request---useeffect---provide-boolean-values-on-whether-dependency-has-changed
Feature Request - useEffect - Provide boolean values on whether dependency has changed.
+1 on this ticket, this is indeed similar to what I’ve posted on https://github.com/facebook/react/issues/22132 (in particular probably the same solution as proposed by @Sangrene https://github.com/facebook/react/issues/22132#issuecomment-901819460) I don’t know what is the best solution for sure, but there is definitely something off in the way useEffect is working currently. It has been going unnoticed, but now that react-hooks/exhaustive-deps is on in many projects (thanks Next.js 😃) it becomes visible that most of us are struggling to use it. The concepts of “dependency” and “effect trigger” are not the same and thus should probably not share the same argument.
Top answer
1 of 6
25

setIsLoading is an async function and you cannot get the state value immediately after update.

setState actions are asynchronous and are batched for performance gains. setState() does not immediately mutate this. Thus the setState calls are asynchronous as well as batched for better UI experience and performance. This applies on both functional/Class components.

From React documentation

React may batch multiple setState() calls into a single update for performance. Because this.props and this.state may be updated asynchronously, you should not rely on their values for calculating the next state. You could read more about this here

If you want to get the updated state value then use useEffect hook with dependency array. React will execute this hook after each state update.

const {useEffect, useState } = React;

const App = (props) => {
  const [isLoading, setIsLoading] = useState(false)
  const buttonHandler = () => {
    setIsLoading(current => !current)
  }

  useEffect( () => {
    console.log(isLoading);
}, [isLoading]);

  return (
    <div>
      <button onClick={buttonHandler} type="button">
        Change
      </button>

      {isLoading? "Loading...": null}
    </div>
  )
}

ReactDOM.render(<App />, document.getElementById('root'));
<script crossorigin src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>

    <div id="root">
      loading.....
    </div>

2 of 6
4

This is the expected behavior. You may want to use useEffect to access the latest value.

Here is a thread discussing the same issue: useState set method not reflecting change immediately

Hope this helps!

🌐
DEV Community
dev.to › alexkhismatulin › update-boolean-state-right-with-react-hooks-3k2i
Update boolean state right with React Hooks - DEV Community
May 11, 2020 - Creating a boolean state and a toggle method for it is a pretty common use case. The spinnet is 100% correct in terms of functionality. But it could be better in terms of performance. Let's see how it can be improved. First things first – useCallback does nothing in this implementation.
Find elsewhere
🌐
DevPress
devpress.csdn.net › react › 62ec4bfb89d9027116a109d6.html
Update boolean state right with React Hooks_reactnative_weixin_0010034-React
August 5, 2022 - Recently I found a construction like this while doing code review: const MyComponent = (props) => { const [isToggled, setIsToggled] = React.useState(false); const toggle = React.useCallback(() => set weixin_0010034 React
🌐
Stack Overflow
stackoverflow.com › questions › 57317696 › how-to-check-if-state-default-boolean-false-is-changing-to-true-with-react-hook
How to check if state default boolean false is changing to true with React Hook useEffect
Not sure if I should use usePrevious for that, because when comparing numbers it works well with this code, but it seems that it is not working when I am trying to check if default boolean is changing. const MemoryPageTwo = ({ disabledAllCards }) => { const boolean = useRef(null); const [ isCurrentBoolean , setLevel ] = useState(false); useEffect(() => { console.log(isCurrentBoolean); if(isCurrentBoolean) { console.log('currentBoolean'); } }, [isCurrentBoolean]); useEffect(() => { const storedBoolean = disabledAllCards ; boolean.current = storedBoolean; return () => storedBoolean }, []); // us
🌐
Ais
ais.com › home › blog › hooked on react: usestate and useeffect
Hooked on React: useState and useEffect - Applied Information Sciences
August 28, 2023 - Having this isn’t required if you leave it as useState(true). React will know that it is a Boolean, and lastly, we have the initial state, which is set to false. This is where you can have the initial value to be whatever you want when the component first renders.
🌐
Stack Overflow
stackoverflow.com › questions › 67683732 › useeffect-always-work-while-using-array-dependency-of-boolean-value
reactjs - useEffect always work while using array dependency of boolean value - Stack Overflow
May 25, 2021 - One solution could be to use a second "mounting" useEffect hook to clear the state when the component unmounts. Note this useEffect has an empty dependency array so it is run only once when the component mounts and strictly returns a cleanup ...
🌐
Stack Overflow
stackoverflow.com › questions › 66208718 › useeffect-not-validating-boolean-values-to-perform-some-action
reactjs - useEffect not validating Boolean values to perform some action - Stack Overflow
February 15, 2021 - Bring the best of human thought and AI automation together at your work. Explore Stack Internal ... I using contextApi for state management, i have checkbox, on checked and unchecked, trying to dispatch ome actions to the store. sample code: import { store } from '../../../shared/store'; function GPSPosition() { const [isEnable, setCheckBoxEnable] = useState(false) useEffect(() => { console.log(isEnable, "in use effect"); setCheckBoxEnable(isEnable) console.log(isEnable, "in use effect after"); if (isEnable) { dispatch({ type: "stopsendingdata", stop_sending: isEnable, data: 'GPS' }) } else {
🌐
Bobby Hadz
bobbyhadz.com › blog › react-toggle-boolean-state
How to toggle a Boolean state in React | bobbyhadz
Note that you shouldn't try to immediately access the boolean state variable after changing it. If you try to access the isLoading state variable immediately after using the setIsLoading function to update it, there is no guarantee that you'll get the current (most up-to-date) value. If you need to listen to state changes, add the state variables to the dependencies array of the useEffect ...
Top answer
1 of 2
1

You can add another useEffect which watches this change, useEffect takes a second argument which is dependency array and the effect gets called if any of the dependency array value changes .

In this case since you need to make a decision based on the nomStatus, you can add it as a dependency to your useEffect

useEffect(() => {
  if (nomStatus) {
    setShowCalender(true);
  }
}, [nomStatus]);
2 of 2
1

You can't since React state updates are asynchronously processed, the nomStatus state update won't be available until the next render cycle. Use the res.data[0].status value to set the showCalendar state.

const [nomStatus, setNomStatus] = useState(false);

useEffect(() => {
  const fetchData = async () => {
    const email = localStorage.getItem("loginEmail");
    try {
      const res = await Axios.get(
        "http://localhost:8000/service/activeStatus",
        {email}
      );
      setNomStatus(res.data[0].status);
      console.log("Get status data :" + res.data[0].status);
      if (res.data[0].status){
        setShowCalender(true);
      }
    } catch (e) {
      console.log(e);
    }
  };
  fetchData();
}, []);

Or you can use a second useEffect hook with a dependency on nomStatus state update to set the showCalendar state.

useEffect(() => {
  const fetchData = async () => {
    const email = localStorage.getItem("loginEmail");
    try {
      const res = await Axios.get(
        "http://localhost:8000/service/activeStatus",
        {email}
      );
      setNomStatus(res.data[0].status);
      console.log("Get status data :" + res.data[0].status);
    } catch (e) {
      console.log(e);
    }
  };
  fetchData();
}, []);

useEffect(() => {
  if (nomStatus){
    setShowCalender(true);
  }
}, [nomStatus]);
🌐
Medium
medium.com › @akashsdas_dev › useeffect-react-hook-a433e9fab3dc
useEffect — React Hook
March 27, 2024 - This happens because objects are compared via reference and not their value. By default, when we read a reactive value from an Effect, we’ve to add it as a dependency. This ensures that your Effect “reacts” to every change of that value.
Top answer
1 of 2
3

EDIT 2022-07-30

After reviewing the codesandbox you shared, it seems you are approaching your state organization incorrectly.

In your case, the parent component calls some API and, if the API returns an error, you want to show an error box as a child component. As soon as the user exits the error box, you want to hide the error box.

In this case, you should not store the state of whether the error box is showing within the child component. Otherwise, the parent will not know whether the child is showing or not, and thus it will not be able to correctly trigger a re-show of the ErrorBox on new validation errors.

Instead, you should store that boolean flag within the parent. Once the API call returns an error, you set the flag to true and show the error box. Within the error box, you should pass an onClose function that, when invoked, toggles the boolean state to false within the parent, which triggers the parent to hide the error box. This way, the error box is not storing whether it is hidden or not (which was causing the inconsistency issue you see in your sandbox).

I have fixed your sandbox accordingly at this url: https://codesandbox.io/s/so-q-73146681-6854489-demo-fixed-94pki1?file=/src/App.js


I would also highly recommend that you read some of the principles that the React documentation lays out regarding handling state and lifting state up:

https://reactjs.org/docs/state-and-lifecycle.html
https://reactjs.org/docs/lifting-state-up.html

(Although the above articles use class components, the principles apply to the useState hook as well)

Here are the relevant snippets:

App.js:

export default function App() {
  const [error, setError] = useState("");
  const [showErrorBox, setShowErrorBox] = useState(false);

  const callApi = () => {
    setError("error");
    setShowErrorBox(true);
  };

  return (
    <div className="App">
      <button onClick={callApi}>Throw Error</button>
      {showErrorBox && (
        <ErrorBox errorData={error} onClose={() => setShowErrorBox(false)} />
      )}
    </div>
  );
}

ErrorBox.js:

const ErrorBox = ({ errorData, onClose }) => {
  console.log("ERROR DATA", errorData);

  return (
    <>
      <div
        className="alert alert-warning alert-dismissible fade show"
        role="alert"
      >
        <strong>Error!</strong>
        <button
          type="button"
          className="close"
          data-dismiss="alert"
          aria-label="Close"
          onClick={onClose}
        >
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
    </>
  );
};

export default ErrorBox;

As a final thought, rather than calling the useState hook and just storing a boolean, I would recommend checking out the useBoolean hook within the usehooks-ts library. It gives you setTrue and setFalse convenience methods by default which can help condense your boolean-toggling code, in addition to many other great hooks that will help you out as you progress in React development.


Original answer

Like krishn kumar modanval said in his comment, you should pass error as a dependency to the dependencies array in useEffect:

useEffect(() => {
    if(error) {
      setShow(true)
    }
}, [error]) // <-- error added here

I recommend checking out the useEffect documentation here, especially the "Optimizing Performance" section where it discusses how the dependencies array works.


(If this solution alone doesn't work for you, we'll need to see how the error prop that you're passing in works with the alert box code that you're showing us. Please create a stackblitz/plunkr with an MVE demonstrating your problem and we can help you debug it better.)

2 of 2
0

it's simple follow this:

onClick={() => setShow(!show)}

this will toggle your state Value every click.

🌐
Stack Overflow
stackoverflow.com › questions › 70769000 › react-usestate-setter-is-not-working-on-a-boolean-value
React useState setter is not working on a boolean value
So sorry for the question, but the problem was due to a template issue, the click also triggered the function which sets the value to true. The confusion arose because the state update useEffect was not called, and that lead me to different line of investigation.