简体   繁体   中英

Input loses focus when javascript map method is used to render it dynamically

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!

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM