I am using useEffect hook and getting a list of users data with fetch call using function getStoreUsers which dispatches an action on response and stores shopUsers(which is an array) inside the redux store.
In array dependency, I am writing [shopUsers]. I don't know why it is causing infinite rendering.
Here is how I am using useEffect hook:
useEffect(() => {
const { getStoreUsers, shopUsers } = props;
setLoading(true);
getStoreUsers().then(() => {
setLoading(false);
}).catch(() => {
setLoading(false);
});
}, [shopUsers]);
I want to re-render component only when data inside shopUsers array changes.
If I write shopUsers.length inside array dependency. It stops to re-render.
But, let's suppose I have have a page which opens up when the user clicks on a userList and updates user data on next page. After the update I want the user to go back to the same component which is not unmounted previously. So, In this case array length remains the same, but data inside in of array index is updated. So shopUsers.length won't work in that case.
You can make a custom hook to do what you want:
In this example, we replace the last element in the array, and see the output in the console.
import React, { useState, useEffect, useRef } from "react";
import ReactDOM from "react-dom";
import { isEqual } from "lodash";
const usePrevious = value => {
const ref = useRef();
useEffect(() => {
ref.current = value;
});
return ref.current;
};
const App = () => {
const [arr, setArr] = useState([2, 4, 5]);
const prevArr = usePrevious(arr);
useEffect(() => {
if (!isEqual(arr, prevArr)) {
console.log(`array changed from ${prevArr} to ${arr}`);
}
}, [prevArr]);
const change = () => {
const temp = [...arr];
temp.pop();
temp.push(6);
setArr(temp);
};
return (
<button onClick={change}>change last array element</button>
)
};
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
Live example here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With