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: It seems that the default value in functional React component gets updated after render. #20851

Closed
DSamuylov opened this issue Feb 20, 2021 · 3 comments
Labels
Status: Unconfirmed A potential issue that we haven't yet confirmed as a bug Type: Question

Comments

@DSamuylov
Copy link

It seems that the default value in functional React component gets updated after render.

React version: 17.0.1

Steps To Reproduce

I created a question on StackOverflow: https://stackoverflow.com/questions/66286856/why-default-value-in-functional-react-component-gets-updated-after-render, but also repeat it here:

const MyComponent = () => {

  // Initialise data with a random value:
  const [data, setData] = React.useState(
    () => {
      const data = _.sampleSize(_.range(5), 3)
      // Print data on initialisation:
      console.log('init data in default:', data)
      return data
    }
  )

  React.useEffect(() => {
    // Print data after the component is rendered:
    console.log('init data after render:', data)
  })

  return (
    <div>{data}</div>
  );
};

The output in console is:

[Log] init data in default: – [0, 3, 1] (3)
[Log] init data after render: – [2, 1, 3] (3)

My understanding is that before the component is rendered, the function under useState is called. The value returned by the function is assigned to data, and the data values is used to render the component on the screen. The function under useState is called only once and we never call setData, so the value should be the same. Maybe I miss something?

Link to code example:

https://codesandbox.io/s/jovial-glade-9jm75?file=/src/App.js

The current behavior

The output in console before and after render is different.

The expected behavior

The output in console before and after render should be the same.

@DSamuylov DSamuylov added the Status: Unconfirmed A potential issue that we haven't yet confirmed as a bug label Feb 20, 2021
@DSamuylov DSamuylov changed the title Bug: Bug: It seems that the default value in functional React component gets updated after render. Feb 20, 2021
@markerikson
Copy link
Contributor

I believe what you're seeing is likely the result of rendering inside of a <StrictMode>, which causes React to double-render components on mount.

If I remove the <StrictMode> in index.js, I see one pair of log statements, with identical values.

@bvaughn
Copy link
Contributor

bvaughn commented Feb 20, 2021

Yeah, please read about <StrictMode>, particularly how we use it in DEV to help expose unsafe side effects:
https://reactjs.org/docs/strict-mode.html#detecting-unexpected-side-effects

This behavior is DEV only (so we don't double render in production builds) and should not affect how your component works so long as there are no side effects. 😄

@gaearon
Copy link
Collaborator

gaearon commented Mar 30, 2022

We've changed the logging behavior to be more intuitive in React 18.
#21783 (comment)

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

No branches or pull requests

4 participants