如何处理ReactGrid中的下拉单元格?

问题描述 投票:0回答:2

如何处理才能让每个select在cell中都有自己的值?我使用 ReactGrid 和 React 版本 16
onchange 似乎有错误,但没有人可以帮助我解决这个问题

import * as React from "react";
import { render } from "react-dom";
import { ReactGrid, Column, Row, CellChange } from "@silevis/reactgrid";
import "@silevis/reactgrid/styles.css";
import "./styles.css";

const getColumns = (): Column[] => [
  { columnId: "col-1", width: 150 },
  { columnId: "col-2", width: 150 }
];

const headerRow: Row = {
  rowId: "header",
  cells: [
    { type: "header", text: "Dropdown:" },
    { type: "header", text: "Data:" }
  ]
};

const getRows = (isDropdownOpened: boolean): Row[] => [
  headerRow,
  {
    rowId: "row-1",
    cells: [
      {
        type: "dropdown",
        values: [
          { value: "react", label: "React" },
          { value: "vue", label: "Vue" },
          { value: "angular", label: "Angular" }
        ],
        isOpen: isDropdownOpened
        // isDisabled: false,
        // selectedValue: "react",
      }
    ]
  },
  {
    rowId: "row-2",
    cells: [
      {
        type: "dropdown",
        values: [
          { value: "react", label: "React" },
          { value: "vue", label: "Vue" },
          { value: "angular", label: "Angular" }
        ],
        isOpen: isDropdownOpened
        // isDisabled: false,
        // selectedValue: "vue",
      }
    ]
  }
];

function App() {
  const [isDropdownOpened, setIsDropdownOpened] = React.useState(false);
  const [selectedValue, setSelectedValue] = React.useState<
    string | undefined
  >();

  const handleChanges = (changes: CellChange[]) => {
    if (Array.isArray(changes) && changes.length > 0) {
      changes.forEach((change) => {
        if (change.newCell && change.newCell.type === "dropdown") {
          if (change.newCell.isOpen !== isDropdownOpened) {
            setIsDropdownOpened(change.newCell.isOpen);
          }
          // updating the value of a selected option
          if (change.newCell.selectedValue !== selectedValue) {
            setSelectedValue(change.newCell.selectedValue);
          }
        }
      });
    }
  };

  const rows = getRows(isDropdownOpened);
  const columns = getColumns();

  return (
    <>
      <ReactGrid rows={rows} columns={columns} onCellsChanged={handleChanges} />
      <h3>You selected: {selectedValue || "none"}</h3>
    </>
  );
}

render(<App />, document.getElementById("root"));

如果有人想对代码进行自定义,真的可以 看起来很简单,但是这方面的文档非常缺乏
如果有人想对代码进行自定义,确实可以 看起来很简单,但是这方面的文档非常缺乏
如果有人想对代码进行自定义,确实可以 看起来很简单,但是这方面的文档非常缺乏

reactjs typescript react-grid-layout
2个回答
0
投票

最好定义一个数组状态来保存每行的值。

const [data, setData] = useState([{ rowId: 0 , isOpen: false, selectedValue: 'react'...}, ...])

然后在处理函数上更新已更改的数据并设置值。但您需要根据新数据重新生成新行。

但是下拉列表更改处理程序似乎无法正常工作,当您打开下拉列表并选择选项时,它会多次触发,然后在关闭时再次触发,并且所选值或值返回未定义。正如您所说,文档不清楚,您似乎需要找到一种方法使其正常工作。


0
投票

检查之前的值与当前值,一切正常。

import { useState } from "react";
import { ReactGrid } from "@silevis/reactgrid";
import "@silevis/reactgrid/styles.css";

const getPeople = () => [
  {
    name: "Thomas",
    surname: "Goldman",
    birth: new Date("1970-12-02"),
    mobile: 574839457,
    company: "Snatia Ebereum",
    occupation: "CEO",
    isActive: true,
    state: "Odisha",
    isOpen: false,
    email: "[email protected]",
  },
  {
    name: "Mathew Lawrence",
    surname: "Joshua",
    birth: new Date("1943-12-02"),
    mobile: 684739283,
    company: "De-Jaiz Mens Clothing",
    occupation: "Technical recruiter",
    isActive: false,
    state: "AP",
    isOpen: false,
    email: "[email protected]",
  },
  {
    name: "Susie Evelyn",
    surname: "Spencer",
    birth: new Date("1976-01-23"),
    mobile: 684739283,
    company: "Harold Powell",
    occupation: "Concrete paving machine operator",
    isActive: true,
    state: "MP",
    isOpen: false,
    email: "[email protected]",
  },
  {
    name: "",
    surname: "",
    birth: undefined,
    mobile: NaN,
    company: "",
    occupation: "",
    isActive: false,
    state: "",
    isOpen: false,
    email: "",
  },
];

const getColumns = () => [
  { columnId: "name", width: 150 },
  { columnId: "surname", width: 150 },
  { columnId: "birth", width: 100 },
  { columnId: "mobile", width: 100 },
  { columnId: "company", width: 150 },
  { columnId: "occupation", width: 150 },
  { columnId: "isActive", width: 100 },
  { columnId: "state", width: 150 },
  { columnId: "email", width: 150 },
];

const headerRow = {
  rowId: "header",
  cells: [
    { type: "header", text: "Name" },
    { type: "header", text: "Surname" },
    { type: "header", text: "Birth Data" },
    { type: "header", text: "Mobile" },
    { type: "header", text: "Company" },
    { type: "header", text: "Occupation" },
    { type: "header", text: "Is Active" },
    { type: "header", text: "State" },
    { type: "header", text: "Email" },
  ],
};

const getRows = (people) => [
  headerRow,
  ...people.map((person, idx) => ({
    rowId: idx,
    cells: [
      { type: "text", text: person.name },
      { type: "text", text: person.surname },
      { type: "date", date: person.birth },
      { type: "number", value: person.mobile },
      { type: "text", text: person.company },
      { type: "text", text: person.occupation },
      { type: "checkbox", checked: person.isActive },
      {
        type: "dropdown",
        selectedValue: person.state,
        values: [
          { label: "Odisha", value: "Odisha" },
          { label: "AP", value: "AP" },
          { label: "MP", value: "MP" },
          { label: "", value: "" },
        ],
        isOpen: person.isOpen,
      },
      { type: "email", text: person.email },
    ],
  })),
];

const applyChangesToPeople = (changes, prevPeople) => {
  changes.forEach((change) => {
    const personIndex = change.rowId;
    const fieldName = change.columnId;
    if (change.type === "text") {
      prevPeople[personIndex][fieldName] = change.newCell.text;
    }
    if (change.type === "date") {
      prevPeople[personIndex][fieldName] = change.newCell.date;
    }
    if (change.type === "number") {
      prevPeople[personIndex][fieldName] = change.newCell.value;
    }
    if (change.type === "checkbox") {
      prevPeople[personIndex][fieldName] = change.newCell.checked;
    }
    if (change.type === "email") {
      prevPeople[personIndex][fieldName] = change.newCell.text;
    }
    if (change.type === "dropdown") {
      if (change.newCell.selectedValue !== change.previousCell.selectedValue) {
        prevPeople[personIndex][fieldName] = change.newCell.selectedValue;
      }
      prevPeople[personIndex]["isOpen"] = change.newCell.isOpen;
    }
  });
  return [...prevPeople];
};

const App = () => {
  const [people, setPeople] = useState(getPeople());

  const rows = getRows(people);
  const columns = getColumns();

  const handleChanges = (changes) => {
    setPeople((prevPeople) => applyChangesToPeople(changes, prevPeople));
  };

  return (
    <>
      <h1>App</h1>
      <ReactGrid rows={rows} columns={columns} onCellsChanged={handleChanges} />
    </>
  );
};

export default App;
© www.soinside.com 2019 - 2024. All rights reserved.