2 years ago

#63783

test-img

Andy Ray

React.js infinite loop when setting dependent state variable inside useEffect()

I'm building a visual graph editor in React using React Flow. I store the nodes in state as nodes. The user can drag and drop element on the graph, modifying the nodes array.

When nodes is updated, I kick off a long-running compilation step. Once the compilation step completes, I need to update the nodes array with data from the compilation result. When I do this, it triggers an infinite loop of compilation.

Here's a shortened version of the compile useEffect hook:

const [compiling, setCompiling] = useState(false);
const [nodes, setNodes] = useState([]);

useEffect(() => {
  setCompiling(true);
  longRunningCompile(nodes, stateA, stateB, stateC, stateD).then(result => {

    setNodes(nodes.map(element => {
      /* merging of compile output and existing nodes */
    }));

    setCompiling(false);
  })
}, [nodes, stateA, stateB, stateC, stateD]);

You can see above, because nodes is a dependency of the useEffect, and I call setNodes inside the useEffect, it re-triggers the compilation infinitely.

The re-compilation has several dependencies. One of them is the user can do something like add a new node (or modify an existing node). Paraphrasing UI element interactions:

<button onClick={() => setNodes([...nodes, { some new node }])}>
<button onClick={() => setStateA(...)}>
<button onClick={() => setStateB(...)}>
<button onClick={() => setStateC(...)}>
<button onClick={() => setStateD(...)}>

I've considered something like trying to juggle a "compiled" flag stored on a ref or the nodes to prevent infinite updates. I'm not sure if that would work. Is there a declarative way to solve this problem?

reactjs

react-hooks

compilation

infinite-loop

0 Answers

Your Answer

Accepted video resources