简体   繁体   English

如何推送元素以响应钩子状态数组

[英]How to push elements to react hooks state array

I am using react-bootstrap-table2 to make HTML tables, I am using a checkbox inside my table to delete the items.我正在使用react-bootstrap-table2来制作 HTML 表格,我正在使用表格中的复选框来删除项目。

SO as per This link , it is mentioned how to get the selected row and then do the next part, here what I am doing is when I click on any checkbox row gets selected, and if I again select any row that I am adding to the array into my state like below因此,根据此链接,提到了如何获取所选行然后执行下一部分,这里我要做的是当我单击任何复选框行被选中时,如果我再次选择要添加到的任何行数组进入我的状态,如下所示

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

My issue is when I unselect the row that value is not getting deleted from my array, and at the time of delete, I have all the data which I have selected once.我的问题是当我取消选择值没有从我的数组中删除的行时,在删除时,我拥有我选择过的所有数据。

  • One more thing which is related to this is when I check any row I want to show delete button and when none of the rows is checked I want to hide the delete button, here select is giving me the boolean value for that, but it is working for each select once I am selecting multiple rows it shows up, but when I unselect any one of them the delete button hides与此相关的另一件事是,当我检查任何行时,我想显示删除按钮,而当没有选中任何行时,我想隐藏删除按钮,这里select为我提供了布尔值,但它是一旦我选择多行,它就会为每个选择工作,但当我取消选择其中任何一个时,删除按钮会隐藏

What I have done for that is something like below我为此所做的事情如下所示

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>
                )}

My full working code 我的完整工作代码

Use a filter method inside your else block to remove that unselected element from the array在 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]);
    },

try to change onSelect function like this尝试像这样更改 onSelect 函数

  onSelect: (row, isSelect, rowIndex, 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);
  }
}

Note that, you don't need to maintain another state for controlling visibility of Delete button.请注意,您不需要维护另一个状态来控制Delete按钮的可见性。

You can perfectly hide/show Delete based on rowData state.您可以根据rowData状态完美地隐藏/显示删除。

Also the code you wrote for handling selected rows works perfectly well.此外,您编写的用于处理选定行的代码运行良好。 Just get rid of rowSelect state and its handlers.只需摆脱rowSelect状态及其处理程序。

And update the rendering of your Delete button based on contents of your rowData as:并根据rowData内容更新“ Delete按钮的呈现为:

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

This is the forked sandbox from yours.这是你的分叉沙箱

Here is one way to implement what you want :这是实现您想要的一种方法:

1.Keep your data in one object, and add an id and isSelect fields 1.将你的数据保存在一个对象中,并添加一个idisSelect字段

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

2.pass this data to useState : 2.将此数据传递给useState

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

3. onSelect : just find the row by id and set isSelect field 3. onSelect :只需按 id 查找行并设置isSelect字段

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

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

4. onSelectAll set isSelect on all rows 4. onSelectAll在所有行上设置isSelect

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

5.for Delete_device just filter the data that is not selected : 5.对于Delete_device只过滤未选中的数据:

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

6.for the delete button, get the selected rows and count them, if the count is > 0 then show the button : 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.Pass the state data to BootstrapTable 7.将状态数据传递给BootstrapTable

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

Complete example 完整示例

I updated your state to use your data and removed the select array from your select logic.我更新了您的状态以使用您的数据并从您的选择逻辑中删除了选择数组。 I also optimized it a bit.我也优化了一下。 Its minor change from your codesandbox sample.它与您的代码和框示例的微小变化。 Also, I recommend you use ids.另外,我建议您使用 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, isSelect, rowIndex, 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", rowIndex, row, isSelect);
        //   setrowSelect((rowData) =>
        //     rowData.filter(
        //       ({ fname, lname }) => row.fname !== fname && row.lname !== lname
        //     )
        //   );
        // }
      },

      onSelectAll: (isSelect, rows, 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", rowData, 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 https://codesandbox.io/s/react-bootstrap-table-x-wus5r?file=/src/App.js

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM