【问题标题】:Why does react component do not re render after changing state为什么反应组件在更改状态后不重新渲染
【发布时间】:2021-04-30 08:39:28
【问题描述】:

index.js

const [todo, setToDo] = useState([]);
useEffect(async() => {
socket.on("receive_message", (message) => {
  let result = todos ? todos : [];
  if (message.sendBy === 'user') {
    let old_index;
    if (result.length > 0) {
      old_index = result.findIndex(item => item.id === message.senderId);
      if (0 >= result.length) {
        var k = 0 - result.length + 1;
        while (k--) {
          result.push(undefined);
        }
      }
      result.splice(0, 0, result.splice(old_index, 1)[0]);
      setTodos(result); // for testing
  }]
});  }, [todos]);

const render =
todos &&
todos.map((item) => {
  return (
    <li
      key={item.id}
      className={activeId.id === item.id ? "person active-user" : "person"}
      data-chat="person1"
      onClick={(e) => historyAccess(item)}
    >
      <div className="user">
        <img
          src={item.profile_pic ? item.profile_pic : "avatars/12.png"}
          alt="Profile Picture"
        />
      </div>
      <p className="name-time">
        <span className="name">{item.name ? item.name : ""}</span>
        {/* <span className="time">{}</span> */}
      </p>
    </li>
  );
});

useEffect 工作正常,并且 settodos 正在将其值更改为对象数组,但它不会重新渲染。它工作得非常好,setTodos 正在改变它的价值并按预期​​工作然后为什么会发生这种情况

【问题讨论】:

  • 您的组件返回什么?此外,此代码包含错误,甚至无法运行。效果不能是async 本身,它们只能调用异步函数。你的状态有时会不一致地命名todo,有时todossetToDosetTodos也是如此。
  • 这是完整的文件吗?我不这么认为。显示完整文件,以便我们了解 JSX 是如何使用的。现在你的const render = 没有返回或任何东西。您是否使用了 create-react-app 或如何设置应用程序?

标签: reactjs redux react-redux react-hooks


【解决方案1】:

问题

Array.prototype.splice 就地改变数组。您将todos 状态的引用保存到局部变量result,然后对其进行变异并将其保存回状态。数组引用永远不会改变。

另外,useEffect 钩子回调不能是 async

解决方案

  1. 先浅拷贝数组,然后对其进行变异。这样 React 就可以协调状态实际上已更新。
  2. 由于您没有 await 任何内容,因此删除 async 声明是安全的

代码:

const [todos, setToDo] = useState([]); // <-- todos is already initially defined

useEffect(() => {
  socket.on("receive_message", (message) => {
    const result = [...todos]; // <-- shallow copy todos

    if (message.sendBy === 'user') {
      ...
      result.splice(0, 0, result.splice(old_index, 1)[0]); // <-- then mutate
      setTodos(result);
    }
  });
}, [todos]);

【讨论】:

    猜你喜欢
    • 2017-03-24
    • 2022-07-08
    • 2021-01-27
    • 2021-06-20
    • 2022-07-12
    • 2019-04-03
    • 2023-03-22
    • 2020-10-07
    • 2020-05-04
    相关资源
    最近更新 更多