Reputation: 3278
I have a code that listens to a server-side event, grabs the event data as object, and pushes it to a state array. However, at the moment I am directly updating the array instead of setting the state via setState
. Otherwise, I'd get a "too many re-rendering" error.
const App = () => {
const [records, setRecords] = useState([]);
console.log(records);
const newRecord = useDataListener({
eventName: "message",
srcURL: "http://localhost:5001/status_stream"
});
// If change into the following lines, code won't work
// if (newRecord !== null) {
// setRecords(oldRecords => [newRecord, ...oldRecords])
//}
// But this looks incorrect, despite being able to render content
if (newRecord !== null) {
records.unshift(newRecord);
}
return (
<div className="ui container">
<Header />
<PaginationBar />
{records.map((x, i) => (
<SummaryLog key={records.length - (i + 1)} record={x} />
))}
</div>
);
};
Does anyone see why using setRecords
could cause too much re-rendering? Thanks!!
Upvotes: 1
Views: 543
Reputation: 12174
Do not mutate the records
. State should be immutable.
Also, fetching data is a side effect. So use useEffect
hook to handle side effects.
useEffect(
() => {
setRecords(oldRecords => ([...oldRecords, newRecord]))
}
, [newRecord]
);
This hook will only run if there are newRecord
s.
Upvotes: 1
Reputation: 4540
Try using useEffect
hook with newRecord
dependency.
useEffect(() => {
setRecords(oldRecords => [...oldRecords, newRecord])
}, [newRecord]);
Upvotes: 1