取消选中React中的复选框时CheckMap状态未更新

时间:2019-05-20 08:32:48

标签: javascript reactjs

这是我第一次开发React应用程序。请忍受我。

我打算在确认对话框中显示键(表中的值)。它可以按预期工作,但是当我勾选然后取消选中复选框时,该键似乎仍在地图中。

我通过检索其键并将其添加到数组中来显示checkedMap。但是,当我尝试取消选中然后调用对话框时,在调试视图中,checkedMap仍然具有未选中的键。

谢谢您的帮助。

import React, { useState, useEffect, useRef } from "react";
//import makeData from "../makeData";
import { useTableState } from "react-table";
import Table from "../TransactionPanelTable";

// Simulate a server
const getServerData = async ({ filters, sortBy, pageSize, pageIndex }) => {
  await new Promise(resolve => setTimeout(resolve, 500));

  // Ideally, you would pass this info to the server, but we'll do it here for convenience
  const filtersArr = Object.entries(filters);

  // Get our base data
  let rows = [];

  rows.push({
    transaction_seq: 1555,
    record_count: 300,
    user_id: "test1",
    updated_at: "09-MAY-19 10.01.45.371373000 PM",
    duration: 5.7
  });

  rows.push({
    transaction_seq: 2666,
    rec_count: 1234,
    user_id: "test2",
    updated_at: "",
    duration: 1.23
  });

  // Apply Filters
  if (filtersArr.length) {
    rows = rows.filter(row =>
      filtersArr.every(([key, value]) => row[key].includes(value))
    );
  }

  // Apply Sorting
  if (sortBy.length) {
    const [{ id, desc }] = sortBy;
    rows = [...rows].sort(
      (a, b) => (a[id] > b[id] ? 1 : a[id] === b[id] ? 0 : -1) * (desc ? -1 : 1)
    );
  }

  // Get page counts
  const pageCount = Math.ceil(rows.length / pageSize);
  const rowStart = pageSize * pageIndex;
  const rowEnd = rowStart + pageSize;

  // Get the current page
  rows = rows.slice(rowStart, rowEnd);

  return {
    rows,
    pageCount
  };
};

export default function({ infinite }) {
  **const [checkedMap, setCheckedMap] = useState(new Map());**
  const [data, setData] = useState([]);
  const [loading, setLoading] = useState(false);
  const currentRequestRef = useRef();

  **let newMap = new Map();**

  const fetchData = async () => {
    setLoading(true);

    // We can use a ref to disregard any outdated requests
    const id = Date.now();
    currentRequestRef.current = id;

    // Call our server for the data
    const { rows, pageCount } = await getServerData({
      filters,
      sortBy,
      pageSize,
      pageIndex
    });

    // If this is an outdated request, disregard the results
    if (currentRequestRef.current !== id) {
      return;
    }

    // Set the data and pageCount
    setData(rows);
    setState(old => ({
      ...old,
      pageCount
    }));

    **rows.forEach(row => newMap.set(row, false));**
    //setCheckedMap(newMap);

    setLoading(false);
  };

  **const handleCheckedChange = transaction_seq => {
    let modifiedMap = checkedMap;
    modifiedMap.set(transaction_seq, !checkedMap.get(transaction_seq));
    setCheckedMap(modifiedMap);
  };**

  const columns = [
    {
      Header: "Transaction(s)",
      className: "left",
      columns: [
        {
          id: "checkbox",
          accessor: "checkbox",
          Cell: ({ row }) => {
            return (
              <input
                type="checkbox"
                className="checkbox"
                checked={checkedMap.get(row.original.transaction_seq)}
                onChange={() =>
                  handleCheckedChange(row.original.transaction_seq)
                }
              />
            );
          },

          sortable: false,
          width: 45
        },
        {
          Header: "Transaction Sequence",
          accessor: "transaction_seq",
          id: "transaction_seq",
          minWidth: 200,
          maxWidth: 300
        },
        {
          Header: "Record count",
          accessor: "record_count",
          width: 300
        },
        {
          Header: "User Id",
          accessor: "user_id",
          width: 300
        },
        {
          Header: "Updated At",
          accessor: "updated_at",
          width: 400
        },
        {
          Header: "Duration",
          accessor: "duration",
          width: 400
        }
      ]
    }
  ];

  // Make a new controllable table state instance
  const state = useTableState({ pageCount: 0 });

  const [{ sortBy, filters, pageIndex, pageSize }, setState] = state;

  // When sorting, filters, pageSize, or pageIndex change, fetch new data
  useEffect(() => {
    fetchData();
  }, [sortBy, filters, pageIndex, pageSize]);

  return (
    <React.Fragment>
      <Table
        {...{
          data,
          **checkedMap,**
          columns,
          infinite,
          state, // Pass the state to the table
          loading,
          manualSorting: true, // Manual sorting
          manualFilters: true, // Manual filters
          manualPagination: true, // Manual pagination
          disableMultiSort: true, // Disable multi-sort
          disableGrouping: true, // Disable grouping
          debug: true
        }}
      />
    </React.Fragment>
  );
}

这是table.js

import styled, { css } from "styled-components";
import React, { useRef, useState, useEffect, useLayoutEffect } from "react";
import { FixedSizeList as List } from "react-window";
import {
  useTable,
  useColumns,
  useRows,
  useFilters,
  useSortBy,
  useExpanded,
  usePagination,
  useFlexLayout
} from "react-table";

export default function MyTable({ loading, infinite, checkedMap, ...props }) {
  const instance = useTable(
    {
      ...props
    },
    useColumns,
    useRows,
    useFilters,
    useSortBy,
    useExpanded,
    usePagination,
    useFlexLayout
  );

  const {
    getTableProps,
    headerGroups,
    rows,
    getRowProps,
    pageOptions,
    page,
    state: [{ pageIndex, pageSize, sortBy, filters }],
    gotoPage,
    prepareRow,
    previousPage,
    nextPage,
    setPageSize,
    canPreviousPage,
    canNextPage
  } = instance;

  const { listRef, rowHeight, height, overscan } = useInfiniteScroll({
    enabled: infinite,
    sortBy,
    filters,
    pageIndex,
    pageSize
  });

  let tableBody;

  const renderRow = (row, index, style = {}) => {
    if (!row) {
      return (
        <Row {...{ style, even: index % 2 }}>
          <Cell>Loading more...</Cell>
        </Row>
      );
    }
    prepareRow(row);
    return (
      <Row {...row.getRowProps({ style, even: index % 2 })}>
        {row.cells.map(cell => {
          const isPivot = row.groupByID === cell.column.id;
          const showAggregate = row.subRows && !isPivot;
          return (
            <Cell {...cell.getCellProps()}>
              {showAggregate ? (
                cell.column.aggregate ? (
                  cell.render("Aggregated")
                ) : null
              ) : (
                <span>
                  {isPivot ? (
                    <span
                      style={{
                        cursor: "pointer",
                        paddingLeft: `${row.depth * 2}rem`,
                        paddingRight: "1rem",
                        whiteSpace: "nowrap"
                      }}
                      onClick={() => row.toggleExpanded()}
                    />
                  ) : null}
                  {cell.render("Cell")}
                  {isPivot ? <span> ({row.subRows.length})</span> : null}
                </span>
              )}
            </Cell>
          );
        })}
      </Row>
    );
  };

  if (infinite) {
    tableBody = (
      <List
        ref={listRef}
        height={height}
        itemCount={rows.length + 1}
        itemSize={rowHeight}
        overscanCount={overscan}
        scrollToAlignment="start"
        {...getRowProps()}
      >
        {({ index, style }) => {
          const row = rows[index];
          return renderRow(row, index, style);
        }}
      </List>
    );
  } else {
    tableBody =
      page && page.length ? page.map((row, i) => renderRow(row, i)) : null;
  }

  let pagination;

  pagination = pageOptions.length ? (
    <Pagination {...getRowProps()}>
      <Cell>
        <Button onClick={() => previousPage()} disabled={!canPreviousPage}>
          Previous
        </Button>{" "}
        <Button onClick={() => nextPage()} disabled={!canNextPage}>
          Next
        </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>{" "}
        <Button onClick={() => reprocessConfirmation()}>Reprocess</Button>
      </Cell>
    </Pagination>
  ) : null;

  function reprocessConfirmation() {
    let confirmation = window.confirm(
      "Do you want to reprocess transaction sequence " +
        Array.from(checkedMap.keys())
    );

    if (confirmation === true) console.log(Array.from(checkedMap.keys()));
    else console.log("CANCEL");
  }

  return (
    <React.Fragment>
      <Table {...getTableProps()}>
        {headerGroups.map(headerGroup => (
          <HeaderRow {...headerGroup.getRowProps()}>
            {headerGroup.headers.map(column => (
              <Header
                {...column.getHeaderProps()}
                sorted={column.sorted}
                sortedDesc={column.sortedDesc}
                sortedIndex={column.sortedIndex}
              >
                <div>
                  <span {...column.getSortByToggleProps()}>
                    {column.render("Header")}
                  </span>{" "}
                </div>
                {column.canFilter ? <div>{column.render("Filter")}</div> : null}
              </Header>
            ))}
          </HeaderRow>
        ))}
        {tableBody}
        <Row {...getRowProps()}>
          {loading ? (
            <Cell>
              <strong>Loading...</strong>
            </Cell>
          ) : (
            <Cell>{rows.length} Total Records</Cell>
          )}
        </Row>
        {pagination}
      </Table>
    </React.Fragment>
  );
}




0 个答案:

没有答案