#Form TextInput won't maintain focus when input is wrapped in another component

1 messages · Page 1 of 1 (latest)

merry quartz
#

I came across an issue which I'm not sure is a bug or just my lack of understanding React.

The problem is that when I'm using useForm's inputProps on a TextInput inside of a component which is defined inside of another component, the input won't maintain focus and prevents me from typing into the input.

App.tsx

  const form = useForm({
    initialValues: {
      test: '',
    },
  });

  return (
    <MantineProvider>
      <div>
        <h1>Hello {name}!</h1>
        <p>Start editing to see some magic happen :)</p>
        <Test inputProps={form.getInputProps('test')} />
      </div>
    </MantineProvider>
  );
};```

Test.tsx
```export default function Test({ inputProps }) {
  const Wrap = () => {
    return <TextInput placeholder="Test..." {...inputProps} />;
  };

  // Doesn't work...
  return <Wrap />;

  // Works...
  // return <TextInput placeholder="Test..." {...inputProps} />;
}```

This can be reproduced here by attempting to focus the input: https://stackblitz.com/edit/stackblitz-starters-dptysf?file=src%2FApp.tsx
To see the working version, comment out the "not working" line and uncomment the "working" line.

My expectation is that both returning `<Wrap>` as well as just returning the `<TextInput>` directly from `<Test>` would result in the same exact thing, but that doesn't appear to be the case.

React + TypeScript starter project

hushed crater
#

This works for me:

const Wrap = () => {
    return <TextInput placeholder="Test..." {...inputProps} />;
  };
  
  return Wrap();
#

You should avoid declaring a component inside another one, if you place Wrap outside of Test , you can use it as you tried in your example:

const Wrap = ({inputProps}) => {
  return <TextInput placeholder="Test..." {...inputProps} />;
};


export default function Test({ inputProps }) {

  return <Wrap inputProps={inputProps}/>;
}

merry quartz
cyan pine
#

You have to think in terms of reference. What is considered a component by React? It’s not the name of the variable (since you can have multiple variables with the same name in different closures). It’s the reference to your variable that React will be able to follow.
By declaring the Wrap variable inside the Test function, your creating a new reference each time the Test function runs (which happens each time the <Test/> instance rerenders)
React has no way to know it’s the same component as previously, therefore it will unmount the previous instance and remount a brand new one.
Hope that helps you understand a bit more how things work under the hood!