'Is there a refactoring pattern to avoid infinite re-renders due to identic data perpetually jumping between parent to child?
Imagine a simple part of a React application that consists of OuterComponent and InnerComponent inside of it. There are instructions these components must follow:
- Whenever the
datainOuterComponentchanges its value, it must overwriteInnerComponent'slocalData's current value. - Whenever the
localDatainInnerComponentchanges its value, it must overwriteOuterComponent'sdata's current value.
Here is the code in question:
import React, { useEffect, useState } from "react";
const InnerComponent = ({ data = [], onChange = null }) => {
const [localData, setLocalData] = useState([]);
useEffect(() => {
if (onChange) onChange(localData);
}, [localData, onChange]);
useEffect(() => {
console.log("render");
setLocalData(data);
}, [data]);
return (
<div>
{localData.map((e) => (
<div>{e}</div>
))}
</div>
);
};
const OuterComponent = () => {
const [data, setData] = useState(["alice", "bob"]);
return <InnerComponent data={data} onChange={setData} />;
};
export default function App() {
return (
<div className="App">
<OuterComponent />
</div>
);
}
Since this situation is something which can arise in a lot of cases and thus is typical, are there any existing time-honored ways of refactoring that code into something free from potential infinite rendering cases? I'm also curious whether there is a way if localData is an array while data is an object that has this array in one of its keys which should be monitored by a child component.
Solution 1:[1]
Yes, in such cases I'd keep a ref of the previous localData in the InnerComponent and add a guard clause, in the useEffect that calls onChange, to test against current localData e.g.:
const prevLocalData = useRef(localData);
useEffect(() => {
if (JSON.stringify(localData) === JSON.stringify(prevLocalData.current)) {
return undefined;
}
onChange(localData);
}, [localData, onChange])
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Ioannis Potouridis |
