Javascript 将材料UI数据网格onSelectionChange传递给react钩子

Javascript 将材料UI数据网格onSelectionChange传递给react钩子,javascript,reactjs,material-ui,Javascript,Reactjs,Material Ui,尝试将材质UI数据网格组件的选定行发送到React挂钩时,站点锁定,出现以下错误: 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 rend

尝试将材质UI数据网格组件的选定行发送到React挂钩时,站点锁定,出现以下错误:

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.
我可能走错了方向,但我希望做的是将当前选定行的数据传递到React钩子中,以便我可以对其进行操作

import React,{useState}来自“React”;
从“@material ui/data grid”导入{DataGrid}”;
常量索引页=()=>{
const[test,setTest]=useState([]);
功能currentlySelected(选择){
设置测试(选择);
控制台日志(测试);
}
常量行=[
{id:1,名称:“示例1”,价格:“$10.99”},
{id:2,名称:“示例2”,价格:“$12.50”}
];
常量列=[
{字段:“名称”,标题名称:“名称”,宽度:300},
{字段:“价格”,标题名称:“价格”}
];
const sortModel=[
{
字段:“名称”,
排序:“asc”
}
];
返回(
{
console.log(newSelection.rows)
//****选择后,下一行将打断页面****
//当前当选(新闻选举)
}}
/>
);
};
导出默认索引扩展;
DataGrid
中,您会注意到一个
onSelectionChange
属性,其中包含一些注释掉的代码。取消对该行的注释,允许
onSelectionChange
更新
test
React钩子是导致页面中断的原因

将当前选定的字段向上推到钩子的正确方式是什么

.

你试过了吗

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
import React,{useState}来自“React”
从“@material ui/data grid”导入{DataGrid}
常量索引页=()=>{
const[test,setTest]=useState([]
功能currentlySelected(选择){
setTest(选择)
console.log(测试)
}
常量行=[
{id:1,名称:“示例1”,价格:“$10.99”},
{id:2,名称:“示例2”,价格:“$12.50”}
]
常量列=[
{字段:“名称”,标题名称:“名称”,宽度:300},
{字段:“价格”,标题名称:“价格”}
]
const sortModel=[
{
字段:“名称”,
排序:“asc”
}
]
返回(
)
}
导出默认索引扩展

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

发生的情况是在渲染
DataGrid
时,它最容易触发
onSelectionChange
。从那里,您可以设置重新呈现网格的状态,该状态调用
onSelectionChange
。。。你进入了一个无限循环

您可以通过以下方式解决此问题:

  • 如果选择更改时传递的选择不等于您在状态中已有的选择,则仅调用
    setTest
  • constindexpage=()=>{
    const[test,setTest]=useState([]);
    功能currentlySelected(选择){
    如果(test!==selections){//我没有写它,但是您需要在这里进行对象比较
    setTest(选择)
    }
    }
    ...
    返回(
    )
    }
    
  • 将所选行存储在ref中
  • constindexpage=()=>{
    const test=useRef({});
    功能currentlySelected(选择){
    test.current=选择;
    }
    ...
    返回(
    )
    }
    

    选项2可能有意义,也可能没有意义,这取决于您想对所选行执行什么操作,但这两个选项中的任何一个都会阻止页面锁定,不幸的是,这也会导致页面无限循环。这里是另一个沙箱,标准React(不是盖茨比)由于一个永无止境的循环而类似地中断。只需取消第40行的注释。我根据以下内容更新了答案:它的性能更好,因为它不会锁定浏览器,但仍然提供以下错误:“警告:超过了最大更新深度。当组件在useEffect内部调用setState时,可能会发生这种情况,但useEffect没有依赖项数组,或者每个渲染都会更改其中一个依赖项。”将数据设置为ref对我的用例很有效,谢谢!
    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> 
      )
    }
    
    const IndexPage = () => {
      const test= useRef({});
    
      function currentlySelected(selections) {
        test.current = selections;
      }
    
     ...
    
      return (
        <div style={{ height: "50vh" }}>
          <DataGrid
            onSelectionChange={currentlySelected}
          />
        </div> 
      )
    }