2 years ago
#63783
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