Skip to content

Bug: functional components are not re-rendered if the provided props look the same #19104

Closed
@danielo515

Description

@danielo515

On previous versions of react, functional components were always re-rendered unless they were memoized. With the latest version, if the props do not change the component does not re-render. While this is an improvement in general, there are certain scenarios where you want to force a re-render, for example to react to some user input that does not change the value, but requires to make operations on the dom. A great example is an input field, where you may need to reposition the cursor even if the input content is the same

React version: 16.13.0

Steps To Reproduce

  1. Create a controlled input component
  2. Handle the state from the parent, for example using useStateHook
  3. Make the state behave to set the input-value to the same value when the user inputs certain value, for example, behave normal for any input except when the user types "aa", then you set the value to always the same "aa" one, not allowing the user to enter more than two a
  4. Even if you add an useEffect inside the input component, the component is not re-rendered

Link to code example:

https://codepen.io/danielo515/pen/KKVdmye?editors=0010

The current behavior

The component does not get re-render if the provided props do not change, even if there is a useEffect hook inside.

The expected behavior

The functional component should re-render unless it is memoized, or at least take in account if there is an use effect hook.

While this may look stupid from the provided example, imagine a controlled number input that automatically formats the user input, adding two decimal positions at the end .00. When the user reaches the dot, he/she may expect to input a dot and let the cursor move after the existing one, however, because the final value hasn't changed (there text still ends at .00 thanks to automatic formatting) the component is not re-rendered, making impossible to re-position the cursor using useEffect hook.

As a workaround, you can add an use-state hook inside the controlled component, so you can store there the raw user input, but that only works until the user tries to input a value that doesn't change the internal state.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions