如何在反应表中使用另一个不确定的复选框列

Posted

技术标签:

【中文标题】如何在反应表中使用另一个不确定的复选框列【英文标题】:how to use one more indeterminate checkbox column in react-table 【发布时间】:2021-10-14 16:35:50 【问题描述】:

我正在使用带有全选复选框的 react-table 显示用户数据。但我想再添加一个复选框列来更改活动/非活动状态。我添加了状态复选框,但是当我选择任何状态复选框时,第一列复选框也会被选中。

https://codesandbox.io/s/condescending-lewin-fcukr?file=/src/App.js

import React from "react";
import styled from "styled-components";
import  useTable, usePagination, useRowSelect  from "react-table";

import makeData from "./makeData";

const Styles = styled.div`
  padding: 1rem;

  table 
    border-spacing: 0;
    border: 1px solid black;

    tr 
      :last-child 
        td 
          border-bottom: 0;
        
      
    

    th,
    td 
      margin: 0;
      padding: 0.5rem;
      border-bottom: 1px solid black;
      border-right: 1px solid black;

      :last-child 
        border-right: 0;
      
    
  

  .pagination 
    padding: 0.5rem;
  
`;

const IndeterminateCheckbox = React.forwardRef(
  ( indeterminate, ...rest , ref) => 
    const defaultRef = React.useRef();
    const resolvedRef = ref || defaultRef;

    React.useEffect(() => 
      resolvedRef.current.indeterminate = indeterminate;
    , [resolvedRef, indeterminate]);

    return (
      <>
        <input type="checkbox" ref=resolvedRef ...rest />
      </>
    );
  
);
const IndeterminateCheckbox2 = React.forwardRef(
  ( indeterminate, ...rest , ref) => 
    const defaultRef = React.useRef();
    const resolvedRef = ref || defaultRef;

    React.useEffect(() => 
      resolvedRef.current.indeterminate = indeterminate;
    , [resolvedRef, indeterminate]);

    return (
      <>
        <input type="checkbox" name="status" ref=resolvedRef ...rest />
      </>
    );
  
);

function Table( columns, data ) 
  // Use the state and functions returned from useTable to build your UI
  const 
    getTableProps,
    getTableBodyProps,
    headerGroups,
    prepareRow,
    page, // Instead of using 'rows', we'll use page,
    // which has only the rows for the active page

    // The rest of these things are super handy, too ;)
    canPreviousPage,
    canNextPage,
    pageOptions,
    pageCount,
    gotoPage,
    nextPage,
    previousPage,
    setPageSize,
    selectedFlatRows,
    state:  pageIndex, pageSize, selectedRowIds 
   = useTable(
    
      columns,
      data
    ,
    usePagination,
    useRowSelect,
    (hooks) => 
      hooks.visibleColumns.push((columns) => [
        // Let's make a column for selection
        
          id: "selection",
          // The header can use the table's getToggleAllRowsSelectedProps method
          // to render a checkbox
          Header: ( getToggleAllPageRowsSelectedProps ) => (
            <div>
              <IndeterminateCheckbox ...getToggleAllPageRowsSelectedProps() />
            </div>
          ),
          // The cell can use the individual row's getToggleRowSelectedProps method
          // to the render a checkbox
          Cell: ( row ) => (
            <div>
              <IndeterminateCheckbox ...row.getToggleRowSelectedProps() />
            </div>
          )
        ,
        ...columns
      ]);
    
  );

  // Render the UI for your table
  return (
    <>
      <pre>
        <code>
          JSON.stringify(
            
              pageIndex,
              pageSize,
              pageCount,
              canNextPage,
              canPreviousPage
            ,
            null,
            2
          )
        </code>
      </pre>
      <table ...getTableProps()>
        <thead>
          headerGroups.map((headerGroup) => (
            <tr ...headerGroup.getHeaderGroupProps()>
              headerGroup.headers.map((column) => (
                <th ...column.getHeaderProps()>column.render("Header")</th>
              ))
            </tr>
          ))
        </thead>
        <tbody ...getTableBodyProps()>
          page.map((row, i) => 
            prepareRow(row);
            return (
              <tr ...row.getRowProps()>
                row.cells.map((cell) => 
                  return (
                    <td ...cell.getCellProps()>cell.render("Cell")</td>
                  );
                )
              </tr>
            );
          )
        </tbody>
      </table>
      /* 
        Pagination can be built however you'd like. 
        This is just a very basic UI implementation:
      */
      <div className="pagination">
        <button onClick=() => gotoPage(0) disabled=!canPreviousPage>
          "<<"
        </button>" "
        <button onClick=() => previousPage() disabled=!canPreviousPage>
          "<"
        </button>" "
        <button onClick=() => nextPage() disabled=!canNextPage>
          ">"
        </button>" "
        <button onClick=() => gotoPage(pageCount - 1) disabled=!canNextPage>
          ">>"
        </button>" "
        <span>
          Page" "
          <strong>
            pageIndex + 1 of pageOptions.length
          </strong>" "
        </span>
        <span>
          | Go to page:" "
          <input
            type="number"
            defaultValue=pageIndex + 1
            onChange=(e) => 
              const page = e.target.value ? Number(e.target.value) - 1 : 0;
              gotoPage(page);
            
            style= width: "100px" 
          />
        </span>" "
        <select
          value=pageSize
          onChange=(e) => 
            setPageSize(Number(e.target.value));
          
        >
          [10, 20, 30, 40, 50].map((pageSize) => (
            <option key=pageSize value=pageSize>
              Show pageSize
            </option>
          ))
        </select>
        <pre>
          <code>
            JSON.stringify(
              
                selectedRowIds: selectedRowIds,
                "selectedFlatRows[].original": selectedFlatRows.map(
                  (d) => d.original
                )
              ,
              null,
              2
            )
          </code>
        </pre>
      </div>
    </>
  );


function App() 
  const columns = React.useMemo(
    () => [
      
        Header: "Name",
        columns: [
          
            Header: "First Name",
            accessor: "firstName"
          ,
          
            Header: "Last Name",
            accessor: "lastName"
          
        ]
      ,
      
        Header: "Info",
        columns: [
          
            Header: "Age",
            accessor: "age"
          ,
          
            Header: "Visits",
            accessor: "visits"
          ,
          
            Header: "Status",
            accessor: "status",
            Cell: ( row ) => (
              <div>
                <IndeterminateCheckbox2 ...row.getToggleRowSelectedProps() />
              </div>
            )
          ,
          
            Header: "Profile Progress",
            accessor: "progress"
          
        ]
      
    ],
    []
  );

  const data = React.useMemo(() => makeData(100000), []);

  return (
    <Styles>
      <Table columns=columns data=data />
    </Styles>
  );


export default App;

【问题讨论】:

你应该发布代码而不是链接 @RaduDiță 立即查看 【参考方案1】:

使用 React 如果你使用 Uesmemo 钩子并在列中传递。

const columns = React.useMemo(
() => [
  
    Header: "data",
    accessor: "data",
    isVisible: true,
    disableFilters: true,
    Cell: ( value, row, column ) => 
      if (row.index === 0) 
        return (
          <div>
            <Input typy="check"
              value=data
              onChange=(e) => 
                handleChange(e, "data");
              
              
              disabled=false
            />
            
          </div>
        );
       else 
        return `$row.original`;
      
    ,
  ,

【讨论】:

有人有解决办法吗? @kuldeep

以上是关于如何在反应表中使用另一个不确定的复选框列的主要内容,如果未能解决你的问题,请参考以下文章

如何在html中创建一个复选框,以使用jQuery隐藏/显示表中的多个列

如何在 React Table 上显示和隐藏某些列?

尝试使用反应在表中查找检查值的总和

检查另一个输入时如何根据一个输入更改值?反应钩子

如何在启动另一个反应音频播放器时停止播放?

如何将选中的数据从复选框保存到数据库