I have an application where I have the Dialog.tsx
which generates a pretty neat InputField that looks always the same.
When I try to type into the TextField it types one character and then loses focus because of the setDocumentName
, since it changes the documentName
value that is used as the defaultValue
for the TextField
App.tsx
:
import { useState } from "react";
import "./App.css";
import * as React from "react";
import { Dialog } from "./Components/Dialog";
function App() {
const [documentName, setDocumentName] = useState("");
return (
<>
<Dialog
id="documentName"
defaultValue={documentName}
onChange={(event: React.ChangeEvent<HTMLInputElement>) => {
setDocumentName(event.target.value);
}}
/>
</>
);
}
export default App;
Dialog.tsx
:
import * as React from "react";
export interface DialogProps {
id: string;
defaultValue?: string;
onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void;
}
export const Dialog: React.FC<DialogProps> = ({
id,
defaultValue,
onChange,
}) => {
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
if (onChange) {
onChange(event);
}
};
return (
<>
<input
key={defaultValue + "-input"}
id={id}
defaultValue={defaultValue}
onChange={handleChange}
/>
</>
);
};
I've tried several Stack Overflow solutions and also asked ChatGPT but never got one working.
Instead of using the defaultValue
as part of key
I give a keyValue
to the component and insert it into the property key
.
Here are some points I got from your code :
- Writing on the TextField update documentName
(in App.tsx)
- documentName
is provided to TextField as prop defaultValue
- TextField's root element use defaultValue
in its key
When the key
attribute change, React destroy the element from the dom and create a new one. Basically you have a new input which by default is not focused.
Most of the time, you use key whan you have to manage a list, which is not your case here. Just remove it should probably fix your issue.