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 Mantine's useForm 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
export const App: FC<{ name: string }> = ({ name }) => {
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 seen here: https://stackblitz.com/edit/stackblitz-starters-dptysf?file=src%2FApp.tsx
To reproduce, attempt to focus the input. 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.
This was happening because React is creating a new reference to the inner "Wrap" component every time "Test" is rerendered. React is unmounting the old instance of "Wrap" and remounting a new instance, which is messing with the state of the TextInput.
Declaring "Wrap" outside of the "Test" component resolves the issue.
const Wrap = ({ inputProps }) => {
return <TextInput placeholder="Test..." {...inputProps} />;
};
export default function Test({ inputProps }) {
return <Wrap inputProps={inputProps}/>;
}