const HeaderField = ({
handleHeaderChange,
removeHeader,
index,
header,
}: any) => (
<HeaderContainer>
<TextField
label="Key"
value={header.key}
onChange={e => handleHeaderChange(e.target.value, 'key', index)}
/>
<TextField
label="Value"
value={header.value}
onChange={e => handleHeaderChange(e.target.value, 'value', index)}
/>
);
const CustomHeadersField = ({ handleChange, fieldKey, categoryKey }: any) => {
const [headers, setHeaders] = React.useState<headersType[] | null>(null);
const addHeader = () => {
const newHeaders = headers ? [...headers] : [];
newHeaders.push({ key: '', value: '' });
setHeaders(newHeaders);
};
const handleHeaderChange = (
value: string,
type: 'key' | 'value',
index: number,
) => {
const newHeaders: any = headers ? [...headers] : [];
if (type === 'key') {
newHeaders[index].key = value;
} else {
newHeaders[index].value = value;
}
setHeaders(newHeaders);
handleChange(newHeaders, fieldKey, categoryKey);
};
return (
<CustomHeadersContainer>
{headers?.map((header, index) => (
<HeaderField
key={Math.random()}
handleHeaderChange={handleHeaderChange}
removeHeader={removeHeader}
index={index}
header={header}
/>
))}
<Button
onClick={addHeader}
variant="contained"
sx={{ width: 'fit-content' }}
>
Add Header
</Button>
</CustomHeadersContainer>
);
};
Add Header button adds a new key-value pair to the headers state, adding two new fields in the form.
Now header.map destroys the old components and renders new one for every key press causing it to lose focus.
I tried moving HeaderField component out of CustomHeadersField. It didn't work.
Thank you for the help!
CodePudding user response:
According to react documentation:
Keys should be stable, predictable, and unique. Unstable keys (like those produced by Math.random()) will cause many component instances and DOM nodes to be unnecessarily recreated, which can cause performance degradation and lost state in child components.
Passing Math.random() as a key is the issue. You can use index as a key if you are not reordering the list. Refer this answer