Home > front end >  Collision betwen useState interdependency and useEffect in React Hooks
Collision betwen useState interdependency and useEffect in React Hooks

Time:01-18

I have a useEffect with dependency A and a function where something will trigger if B is true, looking like this:

const [docs, setDocs] = useState(null);
const [update, setUpdate] = useState(false);

useEffect(() => {
  if (update == true) {
    // do this
  }
}, [docs]);

In another function, i'm setting update to true, and I update docs.

const deleteDocument = (a) => {    
  const newArray = a;
  setUpdate(true);
  setDocs(newArray);

};

The problem is that the useEffect will trigger before update is actually updated, therefore not executing the inner function.

Since I would like to do this the proper way (not adding a timeout), what would be the standard way of dealing with this?

CodePudding user response:

The problem is

  setUpdate(true);
  setDocs(newArray);

Setting a state is an async function, where you cannot wait till update is set before next state change occurs.

useRef (one of many solutions)

const docs = useRef();
const [update, setUpdate] = useState(false);

useEffect(() => {
  if (update == true) {
    // do this
  // use can use "docs" here as "docs.current"
  }
}, [update]);


const deleteDocument = (a) => {    
  const newArray = a;
// set the new value of Docs. Changing 'ref' doesnot trigger a render
  docs.current = newArray;
  setUpdate(true);
};


And you can either create update to useRef or docs to useRef. Anything should work

CodePudding user response:

If you need update to be updated, that means that your useEffect depends on update also. So you should add update as a dependency in the dependency array.

useEffect(() => {
  if (update == true) {
    // do this
  }
}, [update, docs]);

Setting states (setState) is an asynchronous function so you can't rely that one will be executed before or after another.

  • Related