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

14,177

Solution 1

You can simply update your data object for example with an interval in an useEffect:

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

I created a sandbox to show you how it could work. You need to update that to fit your data of course.

Solution 2

for people using remote data and want to refresh

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')
); 

this small line of code can do wonders for you if you want to refresh your data

tableRef.current.onQueryChange()}

make sure you have added tableRef = useRef(); too

Share:
14,177
Burak Ozdemir
Author by

Burak Ozdemir

Updated on June 09, 2022

Comments

  • Burak Ozdemir
    Burak Ozdemir about 2 years

    I am using material-table in my ReactJS project, and I checked it documentation and I don't have a clue how to refresh the table when the data is continuously changing (like every 500ms or so). I appreciate any information.

    The below code is of the data table that I am trying to use. After creating the data table as below, I want to update the values of the elements in rows from incoming UDP messages in a periodical manner. I will be receiving new values in a UDP message in 500 ms periods and I have to update the values.

    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);
              }),
          }}
        />
      );
    }