如何推动元素反应钩子状态数组

问题描述

我正在使用react-bootstrap-table2来制作HTML表格,我在表格内部使用了一个复选框来删除项目。

根据{{​​3}}的

SO,它提到了如何获取选定的行,然后进行下一部分,这就是我在单击任何复选框行时所要做的,如果我再次选择任何行,我要添加到数组中的行,变成如下所示的状态

onSelect: (row,isSelect,rowIndex,e) => {
        if (isSelect === true) {
            setrowData((rowData) => [...rowData,row]);
        } else {
        //  here i need to do something
        }
    },

我的问题是,当我取消选择未从数组中删除值的行时,在删除时,我已经选择了所有数据。

  • 与此相关的另一件事是,当我选中要显示删除按钮的任何行,而当未选中任何行时,我想要隐藏删除按钮时,这里select给了我布尔值值,但是一旦选择了多行,它就会对每个选择起作用,但是当我取消选择其中任何一个时,删除按钮都会隐藏

我为此所做的工作如下

setrowSelect((rowSelect) => [...rowSelect,isSelect]); // this one is inside onSelect callback given by the react-bootstrap-table2 library

           {rowSelect && (
                    <button className="btn Secondary_Button_with_Icon">
                        <i className="ri-upload-cloud-line ri-lg"></i>Register
                    </button>
                )}

This link

解决方法

在else块中使用过滤器方法从数组中删除该未选择的元素

 onSelect: (row,isSelect,rowIndex,e) => {
      if (isSelect === true) {
        setrowData((rowData) => [...rowData,row]);
      } else {
        setrowData((rowData) => rowData.filter((x,i)=>i!==rowIndex))
      }
      setrowSelect((rowSelect) => [...rowSelect,isSelect]);
    },
,

尝试像这样更改onSelect函数

  onSelect: (row,e) => {
  if (isSelect === true) {
    setrowData((rowData) => [...rowData,row]);
    rowSelect.push(true);
    setrowSelect(rowSelect);
  } else {
    setrowData((rowData) => rowData.filter((x,i) => i !== rowIndex));     
      rowSelect.pop();
      setrowSelect(rowSelect);
  }
}
,

请注意,您无需维护其他状态来控制Delete按钮的可见性。

您可以根据rowData状态完美地隐藏/显示Delete。

您编写的用于处理选定行的代码也可以很好地工作。只需摆脱rowSelect状态及其处理程序。

并根据Delete的内容将rowData按钮的呈现方式更新为:

{
    rowData.length ? (
        <button className="btn btn-primary" onClick={Delete_device}>
          <i className="ri-upload-cloud-line ri-lg"></i>Delete
        </button>
      )
    : null
}

这是您的forked sandbox

,

这是实现所需内容的一种方法:

1。将数据保留在一个对象中,并添加一个 id isSelect 字段

const data = [
  {
    id: "id-1",fname: "john",lname: "smith",isSelect: false
  },{
    id: "id-2",fname: "steve",lname: "warn",{
    id: "id-3",fname: "michel",lname: "clark",isSelect: false
  }
];

2。将此数据传递到useState

const [rowData,setrowData] = useState(data);

3。onSelect:只需按ID查找行并设置isSelect字段

onSelect: (row,e) => {
  setrowData((rows) => {
    return rows.map((r) => {
      if (r.id !== row.id) {
        return r;
      }

      return { ...r,isSelect };
    });
  });
},

4。onSelectAll在所有行上设置isSelect

onSelectAll: (isSelect,rows,e) => {
  setrowData((rows) => {
    return rows.map((row) => {
      return { ...row,isSelect };
    });
  });
}

5.for Delete_device仅过滤未选择的数据:

  const Delete_device = () => {
    setrowData((rows) => {
      return rows.filter((row) => !row.isSelect);
    });
  };

6。对于删除按钮,获取选定的行并进行计数,如果计数> 0,则显示按钮:

const selectedRows = rowData.filter((row) => row.isSelect);

  return (
    <div className="App">
      {selectedRows.length > 0 && (
        <button className="btn btn-primary" onClick={Delete_device}>
          <i className="ri-upload-cloud-line ri-lg"></i>Delete
        </button>
      )}

7。将状态数据传递到BootstrapTable

  <BootstrapTable
    bootstrap4
    keyField="fname"
    data={rowData}
    columns={tableData[0].columnsData}
    selectRow={selectRow}
  />

Complete example

,

我更新了您的状态以使用您的数据,并从选择逻辑中删除了选择数组。我也对其进行了优化。与您的codeandbox示例相比,它的微小变化。另外,我建议您使用ID。

import React,{ useState,useMemo } from "react";
import "./styles.css";
import "bootstrap/dist/css/bootstrap.min.css";
import BootstrapTable from "react-bootstrap-table-next";
import "react-bootstrap-table-next/dist/react-bootstrap-table2.min.css";

let tableData = [
  {
    rowsData: [
      {
        fname: "john",lname: "smith"
      },{
        fname: "steve",lname: "warn"
      },{
        fname: "michel",lname: "clark"
      }
    ],columnsData: [
      {
        dataField: "fname",text: "First name",sort: true
      },{
        dataField: "lname",text: "last Name",sort: true
      }
    ]
  }
];

export default function App() {
  const [rowData,setrowData] = useState(tableData[0].rowsData);
  const [rowSelect,setrowSelect] = useState([]);

  const selectRow = useMemo(
    () => ({
      mode: "checkbox",clickToSelect: false,classes: "selection-row",onSelect: (row,e) => {
        setrowSelect((rowData) =>
          isSelect
            ? [...rowData,row]
            : rowData.filter(
                ({ fname,lname }) => row.fname !== fname && row.lname !== lname
              )
        );
        // if (isSelect === true) {
        //   setrowSelect((rowData) => [...rowData,row]);
        // } else {
        //   console.log("onSelect",row,isSelect);
        //   setrowSelect((rowData) =>
        //     rowData.filter(
        //       ({ fname,lname }) => row.fname !== fname && row.lname !== lname
        //     )
        //   );
        // }
      },onSelectAll: (isSelect,e) => {
        if (isSelect === true) {
          setrowSelect(rows);
        } else setrowSelect([]);
      }
    }),[]
  );
  const Delete_device = () => {
    console.log("Delete device",rowData,rowSelect);
    if (rowSelect.length < 1) return;
    setrowData((data) =>
      data.filter(
        ({ fname,lname }) =>
          rowSelect.find((s) => s.fname === fname && s.lname === lname) == null
      )
    );
    setrowSelect([]);
  };
  console.log("App",rowSelect);
  return (
    <div className="App">
      {rowData.length > 0 && (
        <button className="btn btn-primary" onClick={Delete_device}>
          <i className="ri-upload-cloud-line ri-lg"></i>Delete
        </button>
      )}
      <BootstrapTable
        bootstrap4
        keyField="fname"
        data={rowData}
        columns={tableData[0].columnsData}
        selectRow={selectRow}
      />
    </div>
  );
}

https://codesandbox.io/s/react-bootstrap-table-x-wus5r?file=/src/App.js

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...