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: calling calling setState twice inside useEffect creates extra function calls #21371

Closed
ChocolateLoverRaj opened this issue Apr 28, 2021 · 2 comments
Labels
Resolution: Expected Behavior Status: Unconfirmed A potential issue that we haven't yet confirmed as a bug

Comments

@ChocolateLoverRaj
Copy link

React version: 17.0.2

Steps To Reproduce

  1. Create a function component
  2. Call 2 setState functions inside a useEffect hook.
import { FC, useEffect, useState } from 'react'

const resolvedPromise = Promise.resolve()

const Test: FC = () => {
  const [a, setA] = useState(2)
  const [b, setB] = useState(0)

  useEffect(() => {
    let canceled = false

    resolvedPromise.finally(() => {
      console.log(a, b, canceled)
      if (canceled) return
      if (a > 0) {
        setA(a - 1)
        setB(b + 1)
      }
    })

    return () => {
      canceled = true
    }
  }, [a, b])

  return null
}

Link to code example: https://codesandbox.io/s/react-bug-606s4?file=/src/App.tsx

The current behavior

  • b ends up being 1.
  • There is an extra function call when a is 1 and b is 0. I think this is after setA(a - 1) but before setB(b + 1).
  • The function call with 1 0 false was not canceled.
  • The function call with 1 1 true was canceled.

Current console output:

2 0 false
1 0 false 
1 1 true
0 1 false

The expected behavior

  • b ends up being 2
  • No extra function call in between setA() and setB()

Expected console output:

2 0 false
1 1 false
0 2 false
@ChocolateLoverRaj ChocolateLoverRaj added the Status: Unconfirmed A potential issue that we haven't yet confirmed as a bug label Apr 28, 2021
@eps1lon
Copy link
Collaborator

eps1lon commented Apr 28, 2021

Thanks for the report.

A similar issue was reported in #20991. #20991 (comment) hopefully gives a good entrypoint to understand that the reported behavior is expected.

@ChocolateLoverRaj
Copy link
Author

For anyone else with a similar issue as me, I found an npm package called react-use-batched-state. The example works using useBatchedState instead of setState.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Resolution: Expected Behavior Status: Unconfirmed A potential issue that we haven't yet confirmed as a bug
Projects
None yet
Development

No branches or pull requests

2 participants