Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug: useReducer, reducer function gets called twice (possible memory leak) #21416

Closed
hosseini44444 opened this issue May 3, 2021 · 5 comments · Fixed by #22445
Closed

Bug: useReducer, reducer function gets called twice (possible memory leak) #21416

hosseini44444 opened this issue May 3, 2021 · 5 comments · Fixed by #22445
Labels
Component: Reconciler Status: Unconfirmed A potential issue that we haven't yet confirmed as a bug Type: Bug

Comments

@hosseini44444
Copy link

hosseini44444 commented May 3, 2021

React version: 17.0.2

Steps To Reproduce

  1. Create a counter reducer with a top limit (top limit is set externally using a prop or state)
  2. Return the current state if the count reaches the top limit
  3. Try to increment the counter by calling dispatch({type:'INCREMENT'}) a few times after the counter has reached the top limit
  4. Set the top limit to a greater number
  5. You'll see that after increasing the top limit, the reducer callback will be called as much as you'd tried to increment the counter in step 3 and the counter will increment that much

Link to code example: CODE PEN

The current behavior

After setting the top limit to a higher limit, the previous INCREMENT actions which are called before and the reducer have returned the intact state, will be called again and the reducer function will be called as much as you've tried before and the counter will increase that much.

The expected behavior

After setting the top limit to a higher limit, the previous INCREMENT actions which are called before, must not be called again and the Reducer function must not be called again and the counter must stay the same.

@hosseini44444 hosseini44444 added the Status: Unconfirmed A potential issue that we haven't yet confirmed as a bug label May 3, 2021
@eps1lon
Copy link
Collaborator

eps1lon commented May 3, 2021

Thanks for the report.

If I click 2 more times it goes to 6 after increasing the limit. If I click 3 more times it goes to 7 after increasing the limit. But in your repro you say it should increase to 7. Did you either mean "it increases to 6" or "click three more times"?

I forked your repro into a codesandbox and simplified it to a primitive state so that we don't get distracted: https://codesandbox.io/s/react-17-reducer-prop-closure-548bh
Same behavior in React 16: https://codesandbox.io/s/react-16-reducer-prop-closure-forked-fxs5q?file=/src/index.js

@hosseini44444
Copy link
Author

hosseini44444 commented May 3, 2021

You're welcome!
Thanks for the quick response.

You're right, the first time when you set the limit to a greater number, the counter will go up the number of times you've incremented the counter minus one.
The interesting point is that if you click the increment button one extra time and then set the top limit to 10, then the counter will stay the same (5) but if then you set the top limit to 5 again and then click the increment button 1 more time and set the top limit to 10 again you'll see that the counter will increase to 6 this time.
It seems that calls to the reducer get batched.

@hosseini44444
Copy link
Author

hosseini44444 commented May 3, 2021

My current workaround around this is returning a new state by spreading the old state, instead of returning the old state.

return nextCount > limit ? {...state} : { count: nextCount };

Obviously, this approach will cause unnecessary reRenders.

@hosseini44444 hosseini44444 changed the title Bug: useReducer reducer function gets called twice (possible memory leak) Bug: useReducer, reducer function gets called twice (possible memory leak) May 4, 2021
@a-c-sreedhar-reddy
Copy link

same as #17953

@Navaneethan2503
Copy link

i would like to work on this issue

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Component: Reconciler Status: Unconfirmed A potential issue that we haven't yet confirmed as a bug Type: Bug
Projects
None yet
4 participants