首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >每次击键后会失去焦点的响应表过滤器

每次击键后会失去焦点的响应表过滤器
EN

Stack Overflow用户
提问于 2022-01-03 16:56:27
回答 1查看 924关注 0票数 0

我试图从这个示例复制全局筛选器实现:https://react-table.tanstack.com/docs/examples/filtering,我复制了所有的代码,过滤工作正常。但是,由于某种原因,每当我在输入框中输入一个字符时,它就失去了焦点,我需要再次在框中单击back以继续输入。

下面是整个表文件:

代码语言:javascript
复制
import React, { useState } from "react";
import {
  useTable,
  useSortBy,
  useGlobalFilter,
  useAsyncDebounce
} from "react-table";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import {
  faSortUp,
  faSortDown,
  faCheck,
  faEllipsisV
} from "@fortawesome/free-solid-svg-icons";
import { Scrollbars } from "rc-scrollbars";

const IngredientsTable = (props) => {
  const { data, selectedIngredient } = props;

  const [showIngredientCheckID, setShowIngredientCheckID] = useState(-1);

  const columns = React.useMemo(
    () => [
      {
        Header: "Name",
        accessor: "col1" // accessor is the "key" in the data
      },
      {
        Header: "",
        accessor: "col2"
      },
      {
        Header: "Item Number",
        accessor: "col3" // accessor is the "key" in the data
      },
      {
        Header: "EPA Number",
        accessor: "col4"
      },
      {
        Header: "Category",
        accessor: "col5"
      },
      {
        Header: "Modified",
        accessor: "col6"
      }
    ],
    []
  );

  // Define a default UI for filtering
  const GlobalFilter = ({
    preGlobalFilteredRows,
    globalFilter,
    setGlobalFilter
  }) => {
    const count = preGlobalFilteredRows.length;
    const [value, setValue] = useState(globalFilter);
    const onChange = useAsyncDebounce((value) => {
      setGlobalFilter(value || undefined);
    }, 200);

    return (
      <span>
        Filter Ingredients:{" "}
        <input
          value={value || ""}
          onChange={(e) => {
            setValue(e.target.value);
            onChange(e.target.value);
          }}
          placeholder={`${count} records...`}
          style={{
            fontSize: "1.1rem",
            border: "0"
          }}
        />
      </span>
    );
  };

  // Define a default UI for filtering
  function DefaultColumnFilter({
    column: { filterValue, preFilteredRows, setFilter }
  }) {
    const count = preFilteredRows.length;

    return (
      <input
        value={filterValue || ""}
        onChange={(e) => {
          setFilter(e.target.value || undefined); // Set undefined to remove the filter entirely
        }}
        placeholder={`Search ${count} records...`}
      />
    );
  }

  const defaultColumn = React.useMemo(
    () => ({
      // Let's set up our default Filter UI
      Filter: DefaultColumnFilter
    }),
    []
  );

  const filterTypes = React.useMemo(
    () => ({
      // Or, override the default text filter to use
      // "startWith"
      text: (rows, id, filterValue) => {
        return rows.filter((row) => {
          const rowValue = row.values[id];
          return rowValue !== undefined
            ? String(rowValue)
                .toLowerCase()
                .startsWith(String(filterValue).toLowerCase())
            : true;
        });
      }
    }),
    []
  );

  const tableInstance = useTable(
    { columns, data, defaultColumn, filterTypes },
    useGlobalFilter, // useGlobalFilter!
    useSortBy
  );

  const {
    getTableProps,
    getTableBodyProps,
    headerGroups,
    rows,
    prepareRow,
    state,
    preGlobalFilteredRows,
    setGlobalFilter
  } = tableInstance;

  // const showUserCheck = (id) => {};

  const thumbVertical = ({ style, ...props }) => {
    const finalStyle = {
      ...style,
      visibility: "hidden"
    };

    return <div style={finalStyle} {...props} />;
  };

  return (
    <div className={"table-container"}>
      <Scrollbars
        autoHeight
        autoHeightMin={0}
        autoHeightMax={"calc(100vh - 40px)"}
        renderThumbVertical={thumbVertical}
      >
        <>
          <div className={"row mx-auto my-2"}>
            <div className={"col-8"}>
              <GlobalFilter
                preGlobalFilteredRows={preGlobalFilteredRows}
                globalFilter={state.globalFilter}
                setGlobalFilter={setGlobalFilter}
              />
            </div>
          </div>
          <table
            {...getTableProps()}
            className={
              "table table-striped table-hover table-borderless ingredients-table"
            }
          >
            <thead>
              {headerGroups.map((headerGroup, i) => (
                <tr {...headerGroup.getHeaderGroupProps()} key={i}>
                  {headerGroup.headers.map((column, thInd) => (
                    // Add the sorting props to control sorting. For this example
                    // we can add them into the header props
                    <th
                      {...column.getHeaderProps(column.getSortByToggleProps())}
                      key={thInd}
                    >
                      {column.render("Header")}
                      {/* Add a sort direction indicator */}
                      <span>
                        {column.isSorted ? (
                          column.isSortedDesc ? (
                            <FontAwesomeIcon icon={faSortDown} size={"lg"} />
                          ) : (
                            <FontAwesomeIcon icon={faSortUp} size={"lg"} />
                          )
                        ) : (
                          ""
                        )}
                      </span>
                    </th>
                  ))}
                </tr>
              ))}
            </thead>

            <tbody {...getTableBodyProps()}>
              {rows.map((row, ind) => {
                // console.log({ row });
                prepareRow(row);

                return (
                  <tr
                    {...row.getRowProps()}
                    onClick={(e) =>
                      setTheSelectedIngredient(e, row.values.col1)
                    }
                    onMouseEnter={() => setShowIngredientCheckID(row.id)}
                    onMouseLeave={() => setShowIngredientCheckID(-1)}
                    key={ind}
                    className={`${
                      selectedIngredient.name === row.values.col1
                        ? "selected"
                        : ""
                    }`}
                    data-testid={"ingredient-row"}
                  >
                    {row.cells.map((cell, tdInd) => {
                      return (
                        <td {...cell.getCellProps()} key={tdInd}>
                          {tdInd === 0 ? (
                            selectedIngredient.name === row.values.col1 ? (
                              <>
                                <FontAwesomeIcon
                                  icon={faCheck}
                                  className={"white"}
                                />{" "}
                              </>
                            ) : showIngredientCheckID === row.id ? (
                              <>
                                <FontAwesomeIcon
                                  icon={faCheck}
                                  className={"gray"}
                                />{" "}
                              </>
                            ) : (
                              <>
                                <FontAwesomeIcon
                                  icon={faCheck}
                                  className={"clear"}
                                />{" "}
                              </>
                            )
                          ) : (
                            tdInd === 1 && (
                              <FontAwesomeIcon
                                icon={faEllipsisV}
                                className={"three-dots"}
                              />
                            )
                          )}
                          {cell.render("Cell")}
                        </td>
                      );
                    })}
                  </tr>
                );
              })}
            </tbody>
          </table>
        </>
      </Scrollbars>
    </div>
  );
};

export default IngredientsTable;

这里有一个代码沙箱,您可以在这里看到问题的发生。https://codesandbox.io/s/relaxed-benz-co8ub?file=/src/components/pieces/IngredientsTable.js:0-7960在顶部,点击上面写着"100条记录.“的地方。然后试着打字。焦点在每个字符之后留下。我不知道是什么原因造成的。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-01-04 11:36:56

只需将GlobalFilter声明移到IngredientsTable之外,因为每次重新呈现父类都会创建它的新实例,这会导致焦点松散。

固定CSB - https://codesandbox.io/s/bold-browser-mwuxd

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70569052

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档