将Material-UI数据网格onSelectionChange传递给react钩子

时间:2020-10-26 16:17:38

标签: javascript reactjs material-ui

当尝试将Material-UI数据网格组件的选定行发送到React Hook时,站点锁定,并显示以下错误:

const

我可能会以错误的方式进行操作,但是我希望做的是将当前选定行的数据传递到React Hook中,以便我可以对其进行操作。

Warning: Maximum update depth exceeded. This can happen when a component calls setState inside useEffect, but useEffect either doesn't have a dependency array, or one of the dependencies changes on every render.

import React, { useState } from "react"; import { DataGrid } from "@material-ui/data-grid"; const IndexPage = () => { const [test, setTest] = useState([]); function currentlySelected(selections) { setTest(selections); console.log(test); } const rows = [ { id: 1, name: "Example 1", price: "$10.99" }, { id: 2, name: "Example 2", price: "$12.50" } ]; const columns = [ { field: "name", headerName: "Name", width: 300 }, { field: "price", headerName: "Price" } ]; const sortModel = [ { field: "name", sort: "asc" } ]; return ( <> <div style={{ height: "50vh" }}> <DataGrid sortingOrder={["desc", "asc"]} sortModel={sortModel} rows={rows} columns={columns} pageSize={100} rowHeight={38} checkboxSelection onSelectionChange={newSelection => { console.log(newSelection.rows) // **** The following line breaks the page upon selection **** // currentlySelected(newSelection) }} /> </div> </> ); }; export default IndexPage; 内,您会发现DataGrid属性带有一些注释掉的代码。取消注释该行,允许onSelectionChange更新onSelectionChange React Hook是导致页面中断的原因。

将当前选择的字段推到钩子的正确方法是什么?

Code Sandbox Example Link

2 个答案:

答案 0 :(得分:1)

发生的事情是,当您渲染DataGrid时,它最容易触发onSelectionChange。从那里开始,您将设置重新渲染网格的状态,该状态将调用onSelectionChange ...,您将陷入无限循环。

您可以通过以下任一方法解决此问题:

  1. 如果setTest传递的选择不等于您已经拥有的状态,则仅调用onSelectionChange
const IndexPage = () => {
  const [test, setTest] = useState([]);

  function currentlySelected(selections) {
    if (test !== selections) { // I didn't write it in but you'll need to do object comparison here
      setTest(selections)
    }
  }

 ...

  return (
    <div style={{ height: "50vh" }}>
      <DataGrid
        onSelectionChange={currentlySelected}
      />
    </div> 
  )
}
  1. 将选定的行存储在引用中
const IndexPage = () => {
  const test= useRef({});

  function currentlySelected(selections) {
    test.current = selections;
  }

 ...

  return (
    <div style={{ height: "50vh" }}>
      <DataGrid
        onSelectionChange={currentlySelected}
      />
    </div> 
  )
}

选项2可能有意义,也可能没有意义,具体取决于您要对选定的行进行什么操作,但是其中任何一个都应阻止页面锁定

答案 1 :(得分:0)

您尝试过吗?

import React, { useState } from "react"
import { DataGrid } from "@material-ui/data-grid"

const IndexPage = () => {
  const [test, setTest] = useState([])

  function currentlySelected(selections) {
    setTest(selections)
    console.log(test)
  }

  const rows = [
    { id: 1, name: "Example 1", price: "$10.99" },
    { id: 2, name: "Example 2", price: "$12.50" }
  ]

  const columns = [
    { field: "name", headerName: "Name", width: 300 },
    { field: "price", headerName: "Price" }
  ]

  const sortModel = [
    {
      field: "name",
      sort: "asc"
    }
  ]

  return (
    <>
      <div style={{ height: "50vh" }}>
        <DataGrid
          sortingOrder={["desc", "asc"]}
          sortModel={sortModel}
          rows={rows}
          columns={columns}
          pageSize={100}
          rowHeight={38}
          checkboxSelection
          onSelectionChange={setTest}
        />
      </div>
    </>
  )
}

export default IndexPage

请注意初始状态为空数组(useState([])),而onSelectionChange直接触发状态函数。