bradtraversy / mern-tutorial

Goalsetter application from Youtube series
714 stars 456 forks source link

Infinite Loop #3

Open N3OGeorgy opened 2 years ago

N3OGeorgy commented 2 years ago

https://github.com/bradtraversy/mern-tutorial/blob/48ac3db4450ca85994177293c4025a4d158d6702/frontend/src/pages/Dashboard.jsx#L27-L31

I am a newbie in react but there is a infinite loop issue if dispatch(getGoals()) gets rejected. The new state will be state.isError = true from extraReducers getGoals.rejected. Then dispatch(reset()) comes and sets the state state.isError = false, component renders again and the loop starts again.

My fix: dispatch(getGoals()) if(!isError){ dispatch(reset()) }

If someone can come with a linked explanation with the exact reason why this is happening would be great :)

crmaccr commented 2 years ago

I am learning react too. I don't have your answer but how did your fix solve the problem?

crmaccr commented 2 years ago

Thank you, for the response and link to the excellent blog post, it was extremely useful. Its true that there won't be infinite request when the api call succeeds but once it fails and in the clean up function we are updating the state( which the blog post mentions should be avoided) it is causing infinite requests.

On Fri, Apr 1, 2022 at 12:18 AM Matias Bacelar @.***> wrote:

https://github.com/bradtraversy/mern-tutorial/blob/48ac3db4450ca85994177293c4025a4d158d6702/frontend/src/pages/Dashboard.jsx#L27-L31

I am a newbie in react but there is a infinite loop issue if dispatch(getGoals()) gets rejected. The new state will be state.isError = true from extraReducers getGoals.rejected. Then dispatch(reset()) comes and sets the state state.isError = false, component renders again and the loop starts again.

My fix: dispatch(getGoals()) if(!isError){ dispatch(reset()) }

If someone can come with a linked explanation with the exact reason why this is happening would be great :)

An infinite loop will not occur because it is returning inside the useEffect hook, that return is the cleanup function of useEffect , you can read about it here https://blog.logrocket.com/understanding-react-useeffect-cleanup-function/ https://github.com/bradtraversy/mern-tutorial/issues/url

— Reply to this email directly, view it on GitHub https://github.com/bradtraversy/mern-tutorial/issues/3#issuecomment-1084961000, or unsubscribe https://github.com/notifications/unsubscribe-auth/AGIY3YMHNUFS46AVETJWFILVCXVV5ANCNFSM5RKV3XBQ . You are receiving this because you commented.Message ID: @.***>

xuanhung1509 commented 2 years ago

I still haven't understand the ins and outs why the reset() causing the loop. But in my case, adding return after navigate to '/login' fix the problem.

yodkwtf commented 2 years ago

It's a slight bug in the code. The reset function we import should be imported from authSlice instead of goalSlice, since we only want to reset stuff like isError, isSuccess, isLoading. Right now we are also resetting the goals array alongside which is resulting in an infinite loop.

Just fix the reset function import by changing goalSlice to authSlice and everything will work like a charm.

megoon commented 2 years ago

Solved !!!

if (user) {
      dispatch(getGoals());
    }

    return () => {
      dispatch(reset());
    };
Spevak21 commented 2 years ago

Hi, I'm new to React, so consider this comment more of a personal understanding than the answer itself. I got infinite loop when trying to logout user. Testing with a version older than React 18 seems to work just fine without conditioning 'dispatch(getGoals())'. I noticed that the actions in Redux DevTools are showing twice (which is not the case in Brads video) and then while I was trying to figure out why this is happening I came across this: https://reactjs.org/docs/strict-mode.html#ensuring-reusable-state Apparently, in strict mode and development environment, after mounting component "React will simulate immediately unmounting and remounting the component". This may have caused a problem with the useEffect somehow getting in infinite loop in the Dashboard component with 'dispatch(getGoals())' exposed. All of us newbies would appreciate if some more experienced developer could look into this and let us know if this makes any sense or am I on wrong trail. infinite-loop .

IsaiStormBlesed commented 2 years ago

It's a slight bug in the code. The reset function we import should be imported from authSlice instead of goalSlice, since we only want to reset stuff like isError, isSuccess, isLoading. Right now we are also resetting the goals array alongside which is resulting in an infinite loop.

Just fix the reset function import by changing goalSlice to authSlice and everything will work like a charm.

So i was wondering if there is no user the navigate function will execute and then the dispatch? or it executes the return function?

fisayo-dmg commented 2 years ago

instead of using a return which won't unmount I'll suggest this:

if (!user) {
    navigate('/login');
} else {
    dispatch(getGoals());
}

this way when the user isn't valid/logged in then we are not calling the dispatch(getGoals()) action which is what is causing the infinite loop