首页 > 解决方案 > ReactTable中删除行动作后组件的数据状态重置为初始值

问题描述

我在尝试删除 reactTable 上的行时遇到了问题,我完全是图书馆的新手,我有一个表,每行都有一个垃圾按钮。预期的行为是单击垃圾箱,状态更新会删除此行元素,并且表格会刷新而不删除已删除的行。

目前,当我更新状态时,我不知道为什么,它会回到它的初始值,一个空数组。

我在这个 codeSandbox 上做了一个极简主义的例子: https ://codesandbox.io/embed/currying-rain-w9z83?fontsize=14&hidenavigation=1&theme=dark

App.js 包含获取数据并创建列定义的父元素,然后将其传递给子元素。Child 元素只是构建表格。

当您点击垃圾桶按钮时,将调用删除该行的方法,但状态将返回到它的初始值:一个空数组。

从现在开始,我尝试了一些事情,比如禁用 react-table 的自动更新,将方法作为 props 传递,并使 Table 组件中的列定义引用作为 props 传递的函数。

我还尝试制作一个在 reactTable 之外调用相同方法的按钮,但我没有遇到问题,比如状态没有重置,所以我确定问题来自我不知道的 ReactTable也许是内部钩子或其他东西。

所以,目前我完全被卡住了,完全没有想法。

提前感谢您的帮助和时间。

标签: javascriptreactjsreact-table-v7

解决方案


setState 是异步的,所以你需要在这里使用函数版本。每当您需要根据先前状态的值创建新状态时,都是如此。

此外,我删除了 useMemo 钩子并修复了 linter 错误。

不要这么简单地忽略穷举性 linter 规则。它几乎总是正确的。

顺便说一句,回答一些你没有问的问题,如果你的状态会根据另一个状态发生变化,强烈考虑使用 useReducer 而不是 useState。

import "./styles.css";
import React, { useState, useEffect } from "react";
import Table from "./table";

/*eslint-disable no-self-compare*/
export default function Patients() {
  const [patients, setPatients] = useState([]);

  function handlePatientRowDelete(row) {
    setPatients((prev) =>
      patients.filter((item) => item.id !== row.original.id)
    );
  }

  useEffect(() => {
    setPatients([
      {
        id: 1,
        fullname: "Jeanne",
        diagnostic: "check"
      },
      {
        id: 2,
        fullname: "Bernard",
        diagnostic: "check2"
      },
      {
        id: 3,
        fullname: "Jacquot",
        diagnostic: "check3"
      }
    ]);
  }, []);

  const columns = [
    {
      Header: "Actions",
      id: "expander",
      Cell: ({ row }) => (
        <span className="action-icons">
          <span {...row.getToggleRowExpandedProps()}>
            {row.isExpanded ? (
              <i className="bi bi-chevron-down"></i>
            ) : (
              <i className="bi bi-chevron-right"></i>
            )}
          </span>
          <span>
            <i
              className="bi bi-trash-fill"
              onClick={() => handlePatientRowDelete(row)}
            ></i>
          </span>
        </span>
      )
    },
    {
      Header: "Nom complet",
      accessor: "fullname"
    },
    {
      Header: "Diagnostic",
      accessor: "diagnostic"
    }
  ];

  return (
    <div className="container content-table">
      <Table data={patients} columns={columns} />
    </div>
  );
}

推荐阅读