MaterialUI 数据网格加载动画无限循环

mj_*_*mj_ 3 reactjs material-ui

我正在使用 Material-UI Data-Grid,并且正在运行用于服务器端数据访问的教程网格。这是用 React 编写的,我遇到了加载圈永久旋转的问题。我设置了一个断点React.useEffect,然后我看到它被一遍又一遍地击中。handlePageChange似乎没有参与无限循环。

稍微考虑一下,我觉得状态正在改变,这会触发整个事情再次执行,因此循环。停止这件事的条件是什么?

import * as React from 'react';
import { DataGrid } from '@material-ui/data-grid';

function loadServerRows(page, data) {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve(data.rows.slice(page * 5, (page + 1) * 5));
    }, Math.random() * 500 + 100); // simulate network latency
  });
}

export default function App() {

  const data = {
    rows: [
      { id: 1, col1: 'Hello', col2: 'World' },
      { id: 2, col1: 'XGrid', col2: 'is Awesome' },
      { id: 3, col1: 'Material-UI', col2: 'is Amazing' },
    ],
    columns: [
      { field: 'col1', headerName: 'Column 1', width: 150 },
      { field: 'col2', headerName: 'Column 2', width: 150 },
    ],
    rowLength: 100,
    maxColumns: 6
  }

  const [page, setPage] = React.useState(0);
  const [rows, setRows] = React.useState([]);
  const [loading, setLoading] = React.useState(false);

  const handlePageChange = (params) => {
    setPage(params.page);
  };

  React.useEffect(() => {
    let active = true;

    (async () => {
      setLoading(true);
      const newRows = await loadServerRows(page, data);

      if (!active) {
        return;
      }

      setRows(newRows);
      setLoading(false);
    })();

    return () => {
      active = false;
    };
  }, [page, data]);

  return (
    <div style={{ height: 400, width: '100%' }}>
      <DataGrid
        rows={rows}
        columns={data.columns}
        pagination
        pageSize={5}
        rowCount={100}
        paginationMode="server"
        onPageChange={handlePageChange}
        loading={loading}
      />
    </div>
  );
}

Run Code Online (Sandbox Code Playgroud)

Spa*_*atz 5

在您的代码中,每次渲染时数据都会发生变化。作为一个选项,您可以使用useRef存储数据(或者只是将其全局移出组件):

import React from 'react'
import { DataGrid } from '@material-ui/data-grid'


function loadServerRows(page, data) {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve(data.rows.slice(page * 5, (page + 1) * 5))
    }, Math.random() * 500 + 100) // simulate network latency
  })
}

function App() {
  const data = React.useRef({
    rows: [
      { id: 1, col1: 'Hello', col2: 'World' },
      { id: 2, col1: 'XGrid', col2: 'is Awesome' },
      { id: 3, col1: 'Material-UI', col2: 'is Amazing' },
    ],
    columns: [
      { field: 'col1', headerName: 'Column 1', width: 150 },
      { field: 'col2', headerName: 'Column 2', width: 150 },
    ],
    rowLength: 100,
    maxColumns: 6
  })
  const [page, setPage] = React.useState(0)
  const [rows, setRows] = React.useState([])
  const [loading, setLoading] = React.useState(false)

  const handlePageChange = (params) => {
    setPage(params.page)
  }

  React.useEffect(() => {
    let active = true;

    (async () => {
      setLoading(true)
      const newRows = await loadServerRows(page, data.current)

      if (!active) {
        return
      }

      setRows(newRows)
      setLoading(false)
    })()

    return () => {
      active = false
    }
  }, [page, data])

  return (
    <div style={{ height: 400, width: '100%' }}>
      <DataGrid
        rows={rows}
        columns={data.current.columns}
        pagination
        pageSize={5}
        rowCount={100}
        paginationMode="server"
        onPageChange={handlePageChange}
        loading={loading}
      />
    </div>
  )
} 
Run Code Online (Sandbox Code Playgroud)