Как установить столбцы на стороне сервера, содержащие элементы JSX в таблице материалов? - PullRequest
0 голосов
/ 11 марта 2020

Пожалуйста, проверьте эту песочницу, чтобы увидеть проблему:

https://codesandbox.io/s/server-generated-mt-ooc3e

Я стремлюсь иметь файл json, который может включить или отключить функцию в указанной ячейке c. Проблема здесь в том, что столбцы содержат обработчики, которые генерируются только один раз при первом использовании. И, таким образом, функция обработчика запускается только один раз при первом рендеринге, для ее решения я вставил состояние, которое изменяется при щелчке, как зависимость для useEffect, что означает, что он генерирует новые обработчики. Проблема в том, что это слишком медленно. Я думал о разделении на useEffect для столбцов и useEffect для данных, но это кажется плохим решением.

import React, { useState, useEffect, useCallback } from "react";
import MaterialTable from "material-table";
import styled from "styled-components";

// ALL ICONS IMPORT AND REF //
import { forwardRef } from "react";

import AddBox from "@material-ui/icons/AddBox";
import ArrowDownward from "@material-ui/icons/ArrowDownward";
import Check from "@material-ui/icons/Check";
import ChevronLeft from "@material-ui/icons/ChevronLeft";
import ChevronRight from "@material-ui/icons/ChevronRight";
import Clear from "@material-ui/icons/Clear";
import DeleteOutline from "@material-ui/icons/DeleteOutline";
import Edit from "@material-ui/icons/Edit";
import FilterList from "@material-ui/icons/FilterList";
import FirstPage from "@material-ui/icons/FirstPage";
import LastPage from "@material-ui/icons/LastPage";
import Remove from "@material-ui/icons/Remove";
import SaveAlt from "@material-ui/icons/SaveAlt";
import Search from "@material-ui/icons/Search";
import ViewColumn from "@material-ui/icons/ViewColumn";

const tableIcons = {
  Add: forwardRef((props, ref) => <AddBox {...props} ref={ref} />),
  Check: forwardRef((props, ref) => <Check {...props} ref={ref} />),
  Clear: forwardRef((props, ref) => <Clear {...props} ref={ref} />),
  Delete: forwardRef((props, ref) => <DeleteOutline {...props} ref={ref} />),
  DetailPanel: forwardRef((props, ref) => (
    <ChevronRight {...props} ref={ref} />
  )),
  Edit: forwardRef((props, ref) => <Edit {...props} ref={ref} />),
  Export: forwardRef((props, ref) => <SaveAlt {...props} ref={ref} />),
  Filter: forwardRef((props, ref) => <FilterList {...props} ref={ref} />),
  FirstPage: forwardRef((props, ref) => <FirstPage {...props} ref={ref} />),
  LastPage: forwardRef((props, ref) => <LastPage {...props} ref={ref} />),
  NextPage: forwardRef((props, ref) => <ChevronRight {...props} ref={ref} />),
  PreviousPage: forwardRef((props, ref) => (
    <ChevronLeft {...props} ref={ref} />
  )),
  ResetSearch: forwardRef((props, ref) => <Clear {...props} ref={ref} />),
  Search: forwardRef((props, ref) => <Search {...props} ref={ref} />),
  SortArrow: forwardRef((props, ref) => <ArrowDownward {...props} ref={ref} />),
  ThirdStateCheck: forwardRef((props, ref) => <Remove {...props} ref={ref} />),
  ViewColumn: forwardRef((props, ref) => <ViewColumn {...props} ref={ref} />)
};

// ----------------------------- //

export default function PositioningActionsColumn() {
  const [stateColumns, setStateColumns] = useState([]);
  const [stateData, setStateData] = useState([]);
  const [isOpen, setIsOpen] = useState(true);

  useEffect(() => {
    fetchTable();
  }, [isOpen]);

  const fetcher = async urlName => {
    const urls = {
      columnsUrl: "https://api.myjson.com/bins/128vkm",
      dataUrl: "https://api.myjson.com/bins/1adefq"
    };

    const fetchedData = await fetch(urls[urlName]);
    const jsonData = await fetchedData.json();
    return jsonData;
  };

  const fetchTable = async () => {
    const jsonColumns = await fetcher("columnsUrl");
    const jsonData = await fetcher("dataUrl");

    columnsGenerator(jsonColumns);
    setStateData(jsonData);
  };

  const columnsGenerator = jsonColumns => {
    const dropDown = <DropDown isOpen={isOpen} />;

    const newColumns = jsonColumns.map(columnHeader => {
      const title = (
        <>
          <ObjTitle onClick={handleClick}>{columnHeader.title}</ObjTitle>
          {columnHeader.includeDropDown && dropDown}
        </>
      );
      const newHeader = { ...columnHeader, title };
      return newHeader;
    });

    setStateColumns(newColumns);
  };

  // const handleClick = () => {
  //   setIsOpen(!isOpen);
  // };

  const handleClick = useCallback(() => setIsOpen(current => !current), []);

  return (
    <>
      <MaterialTable
        title="Editable Preview"
        icons={tableIcons}
        columns={stateColumns}
        data={stateData}
        options={{ draggable: false, selection: true }}
      />
      <Changing isOpen={isOpen} />
    </>
  );
}

const ObjTitle = styled.div``;

const DropDown = styled.div`
  width: 60px;
  height: 60px;
  background: steelblue;
  display: ${({ isOpen }) => (isOpen ? "block" : "none")};
`;

const Changing = styled.div`
  height: 100px;
  width: 100px;
  background: ${({ isOpen }) => (isOpen ? "black" : "red")};
`;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...