TransWikia.com

React passing down hooks causes rerender and loss of focus on input

Stack Overflow Asked by Sunyatasattva on February 1, 2021

I’ve got a parent component in which I initialize some piece of state, which I then pass down to the children components so that they can update that. However, when the update is triggered, the component tree is re-rendered and my inputs lose focus. Adding a key did not help.

// App.tsx

export function App(props) {
  const useVal = useState("");

  return (
    <Router>
      <Switch>
        <Route
          exact
          path="/"
          component={() => (
            <StartScreen
              useVal={useVal}
            />
          )}
        />
        // ...
    </Router>
  );
}
// StartScreen.tsx

interface StartScreenProps {
  useVal: [string, React.Dispatch<React.SetStateAction<string>>];
}

function bindState<T>(
  [value, setState]: [T, React.Dispatch<React.SetStateAction<T>>]
) {
  return {
    value,
    onChange: ({ value }: { value: T }) => setState(value)
  }
}

export const StartScreen = (props: StartScreenProps) => {
  return (
    <form>
      <InputField
        key="myInput"
        {...bindState(props.useVal)}
      />
    </form>
  );
}

So, now when I start typing on my InputField (which is basically a wrapper on an <input>) on StartScreen.tsx, the input constantly loses focus as the component is totally re-rendered (I can see it in the DOM).

One Answer

This happens because you are passing a function to the Route's component prop (I assume you are using react-router-dom) :

From the docs :

If you provide an inline function to the component prop, you would create a new component every render. This results in the existing component unmounting and the new component mounting instead of just updating the existing component.


To solve this problem use the render prop :

    <Route
      exact
      path="/"
      render={() => (
        <StartScreen
          useVal={useVal}
        />
      )}
    />

This allows for convenient inline rendering and wrapping without the undesired remounting explained above.

Answered by Mohamed Ramrami on February 1, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP