ReactJS中数据变化时如何刷新Material-Table(Material-ui)组件

How to refresh Material-Table (Material-ui) component in ReactJS when data changes

我在我的 ReactJS 项目中使用 material-table,我检查了它的文档,但我不知道如何在数据更新时刷新 table不断变化(比如每 500 毫秒左右)。我很感激任何信息。

下面的代码是我尝试使用的数据table。如下创建数据 table 后,我想定期更新来自传入 UDP 消息的行中元素的值。我将在 500 毫秒周期内在 UDP 消息中接收新值,我必须更新这些值。

import React from 'react';
import { forwardRef } from 'react';
import MaterialTable from 'material-table';

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 ElementsTable() {
  const [state, setState] = React.useState({
    columns: [
      { title: 'Element Name', field: 'elmName' },
      { title: 'Value', field: 'elmVal' },
      { title: 'Direction', field: 'msgDirection',
        lookup: { 1: 'INCOMING', 2: 'OUTGOING' }
      },
      {
        title: 'Value Type',
        field: 'valType',
        lookup: { 1: 'Engineering', 2: 'Raw' },
      },
    ],
    data: [
      { elmName: 'Elem1', elmVal: 'STATUS_ON', msgDirection: 1, valType: 1 },
      { elmName: 'Elem2', elmVal: 'STATUS_OFF', msgDirection: 2, valType: 2 },
      { elmName: 'Elem2', elmVal: 'STATUS_ON', msgDirection: 1, valType: 1 },
    ],
  });

  return (
    <MaterialTable
      title="Element List"
      icons={tableIcons}
      columns={state.columns}
      data={state.data}
      editable={{
        onRowAdd: newData =>
          new Promise(resolve => {
            setTimeout(() => {
              resolve();
              setState(prevState => {
                const data = [...prevState.data];
                data.push(newData);
                return { ...prevState, data };
              });
            }, 600);
          }),
        onRowUpdate: (newData, oldData) =>
          new Promise(resolve => {
            setTimeout(() => {
              resolve();
              if (oldData) {
                setState(prevState => {
                  const data = [...prevState.data];
                  data[data.indexOf(oldData)] = newData;
                  return { ...prevState, data };
                });
              }
            }, 600);
          }),
        onRowDelete: oldData =>
          new Promise(resolve => {
            setTimeout(() => {
              resolve();
              setState(prevState => {
                const data = [...prevState.data];
                data.splice(data.indexOf(oldData), 1);
                return { ...prevState, data };
              });
            }, 600);
          }),
      }}
    />
  );
}

您可以简单地更新您的数据对象,例如使用 useEffect 中的间隔:

 useEffect(() => {
    const timer = setInterval(() => {
      setData(prevData => [
        {
          ...prevData[0],
          value: Math.round(Math.random() * 1000)
        }
      ]);
    }, 500);
    return () => clearInterval(timer);
}, []);

我创建了一个 sandbox 来向您展示它是如何工作的。当然,您需要更新它以适合您的数据。

对于使用远程数据并想要刷新的人

import { createMuiTheme } from '@material-ui/core/styles';
import React, { useRef } from 'react';
import ReactDOM from 'react-dom';
import MaterialTable from './material-table';
const App = () => {
  tableRef = useRef();
    return (
        <div style={{ maxWidth: '100%', direction }}>        
              <MaterialTable
                tableRef={tableRef}
                columns={[
                  {
                    title: 'Avatar',
                    field: 'avatar',
                    render: rowData => (
                      <img
                        style={{ height: 36, borderRadius: '50%' }}
                        src={rowData.avatar}
                      />
                    ),
                  },
                  { title: 'Id', field: 'id' },
                  { title: 'First Name', field: 'first_name' },
                  { title: 'Last Name', field: 'last_name' },
                ]}
                data={query =>
                  new Promise((resolve, reject) => {
                    let url = 'https://reqres.in/api/users?';
                    url += 'per_page=' + query.pageSize;
                    url += '&page=' + (query.page + 1);
                    fetch(url)
                      .then(response => response.json())
                      .then(result => {
                        resolve({
                          data: result.data,
                          page: result.page - 1,
                          totalCount: result.total,
                        })
                      });
                  })
                }
                title="Remote Data Example"
              />
          <button
            onClick={() => tableRef.current.onQueryChange()}
          >
            ok
          </button>
        </div>
    );
}

ReactDOM.render(
  <App />,
  document.getElementById('app')
); 

如果您想刷新数据,这一小行代码可以为您创造奇迹

tableRef.current.onQueryChange()}

确保您也添加了 tableRef = useRef();