简体   繁体   中英

How to update state properly in react hooks

So, The problem is that whenever I press the delete button, it just removes the deletes the last input and the button regardless of the index. I've tried to change the key to key={ ${index}${name}}`, this won't work that well, because the inputs are changeable (in main code) and that makes thing messed up. How can I make delete properly according to indexes??

function App() {
  const [names, setNames] = React.useState(["First", "Second",'third','fourth']);
  const onNameDelete = useCallback((index: number) => {
    setNames((prev) => {
      const name = names[index];
      return prev.filter(x => x != name);
    });
  }, [names]);

  return (
    <div>
      {names.map((name, index) => (
        <Child
          key={index}
          name={name}
          index={index}
          onDelete={onNameDelete}
        />
      ))}
    </div>
  );
}
interface ChildProps {
  name: string;
  index: number;
  onDelete: (index: number) => void;
}

export const Child: React.FC<ChildProps> = React.memo(
  ({ name, index, onDelete }) => {
    return (
      <div>
        <input
          defaultValue={name}
        />
        <button onClick={() => onDelete(index)}>delete</button>
      </div>
    );
  }

Here goes:

function App() {
  const [names, setNames] = React.useState(
    ["First", "Second",'third','fourth'].map((name, index) => ({ id: index, name }))
  );
  const onNameDelete = useCallback((index: number) => {
    setNames((prev) => prev.filter({ id } => id !== index));
  }, [names]);

  return (
    <div>
      {names.map(({ id, name }) => (
        <Child
          key={id}
          name={name}
          index={id}
          onDelete={onNameDelete}
        />
      ))}
    </div>
  );
}
interface ChildProps {
  name: string;
  index: number;
  onDelete: (index: number) => void;
}

export const Child: React.FC<ChildProps> = React.memo(
  ({ name, index, onDelete }) => {
    return (
      <div>
        <input
          defaultValue={name}
        />
        <button onClick={() => onDelete(index)}>delete</button>
      </div>
    );
  }

Instead of an array for storing names, please use object array:

const [names, setNames] = React.useState(
    ["First", "Second",'third','fourth'].map((name, index) => ({ id: index, name }))
  );

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