Reputation: 486
I was trying to run a component on initial run i was trying to dispatch the state value to another component
while running useEffect in particular component, useEffect is running continuously UPDATE:
I am having a dropdown too whenever i change from dropdownthe useEffect runs and set the previous value to state
const handleChange = (event) => {
console.log("Role changing")
console.log(event.target.value)
setStates(event.target.value);
dispatch({
type: "SettingROLE",
payload: states
})
};
const { dispatch , state: authState } = useContext(AuthContext);
const authMenus = JSON.parse(sessionStorage.getItem("menus")) || []
const [states, setStates] = useState();
useEffect(() => {
console.log("Inside of header useEffect")
const roleid = authMenus.roles[0];
if(roleid) setStates(roleid.role)
dispatch({
type: "SettingROLE",
payload: states
})
}, [authMenus.roles , dispatch , states]);
I tried to remove the dependency of the useEffect but then dispatch is not working it does not dispatch the value of state
Upvotes: 0
Views: 1277
Reputation: 7239
useEffect
runs anytime a value in the dependency array changes. If it's running continuously, it's because a value is changing. Objects are compared by reference, so any value created in the component will have a new reference each time it's rendered.
In this instance, const authMenus = JSON.parse(sessionStorage.getItem("menus")) || []
is going to create a new reference type every time the component renders and that's triggering an infinite loop.
There are a lot of ways to solve the problem depending on what you are wanting to accomplish.
You can parse it outside the component by moving that code above it.
You can add it to its own useEffect like another answer.
You can store it in a useRef
, so it doesn't trigger a rerender.
https://reactjs.org/docs/hooks-reference.html#useref
const authMenus = useRef(JSON.parse(sessionStorage.getItem("menus")) || []);
You could also use useMemo
if you have dependencies that you want to trigger the value to update.
https://reactjs.org/docs/hooks-reference.html#usememo
const authMenus = useMemo(() => JSON.parse(sessionStorage.getItem("menus")) || [],[someDependency]);
Upvotes: 1
Reputation: 75
if you only want to dispatch on initial run,simply passing [] in dependencies should work!
Also, calling setStates inside useEffect is causing infinite loops!You can move the code except dispatch to outside of useEffect
Upvotes: 0
Reputation: 1
You should separate your logic into two useEffect
hooks :
useEffect(() => {
dispatch({
type: "SettingROLE",
payload: states
})
}, [ dispatch , states]);
useEffect(() => {
const roleid = authMenus.roles[0];
if(roleid) setStates(roleid.role)
}, [authorMenus]);
since you're updating a state that's a dependency which causes an infinite rendering.
Upvotes: 1