反应不呈现新状态

时间:2020-01-14 01:12:36

标签: reactjs react-hooks

我正在尝试学习新的React钩子。我编写了一个简单的待办事项列表,用户可以输入输入以创建新的待办事项,然后单击待办事项以将其删除。但是,在删除待办事项后,它不会重新渲染。

这是我的代码

import React, { useState, Fragment } from "react";

const Todo = () => {
  const [inputVal, setInput] = useState("");
  const [list, setList] = useState([]);
  const handleInput = e => {
    setInput(e.target.value);
  };
  const handleClick = () => {
    setList([...list, inputVal]);
    setInput("");
  };
  const handleDelete = index => {
    setList([...list.splice(index, 1)]);
    console.log(list);
  };
  const renderList = () =>
    list.map((item, index) => {
      return (
        <div key={index} onClick={() => handleDelete(index)}>
          {item}
        </div>
      );
    });
  return (
    <Fragment>
      <div>
        <input value={inputVal} onChange={handleInput} />
        <button onClick={handleClick}>submit</button>
      </div>
      <ul>{renderList()}</ul>
    </Fragment>
  );
};

export default Todo;

1 个答案:

答案 0 :(得分:1)

您在这里有两个问题。

  1. array.splice正在变异并返回删除的项目。 当您运行
setList([...list.splice(index, 1)]);

这将从对象list中删除一项,然后调用setList([removed_item])

您可以将这一行替换为

setList(list.slice(0, index).concat(list.slice(index + 1))

当前正在发生的事情是,您将状态设置为与以前相同(但已突变)的对象,因此不会触发重新渲染。

  1. 您没有正确使用key属性。您可以阅读文档here

如果项的顺序可能更改,我们不建议使用索引作为键。这可能会对性能产生负面影响,并可能导致组件状态出现问题。

您的键应唯一地标识待办事项列表的元素,而无需引用列表本身。该项目中的文本是一个不错的选择,但可能存在非唯一性的问题。

当您重新渲染待办事项列表时,React使用按键来决定要重新渲染哪些子代。如果使用索引作为键,然后删除索引0处的项目,则不会告知第0个子元素更新为新的第0个元素,因为它仍然获得相同的键。