Search code examples
reactjsmaterial-table

How to use UseEffect() hook to load data from the backend to material table?


I'm new to react , and I'm trying to use the UseEffect hook to make an http request to my backend to fetch some data and then display it in materialTable , but the data in state doesn't update until the second render which causes an empty dataTable. Here's my code :

export default function MembersList() {
  const [state, setState] = React.useState({
    columns: [
      { title: "First Name", field: "firstName" },
      { title: "Last Name", field: "lastName" }
    ],
    data: []
  });

  useEffect(() => {
    async function fetchData() {
      const result = await axios("http://localhost:3300/members");
      return result;
    }
    fetchData().then(result => setState({ data: result.data }));
    console.log("useEffect hook is called");
  }, []);

  console.log("state.data", state.data);
  return state.data.length === 0 ? (
    "no data to display"
  ) : (
    <MaterialTable
      title="Members List"
      columns={state.columns}
      data={state.data}
      editable={{
        onRowAdd: newData =>
          new Promise(resolve => {
            setTimeout(() => {
              resolve();
              const data = [...state.data];
              data.push(newData);
              setState({ ...state, data });
            }, 600);
          }),
        onRowUpdate: (newData, oldData) =>
          new Promise(resolve => {
            setTimeout(() => {
              resolve();
              const data = [...state.data];
              data[data.indexOf(oldData)] = newData;
              setState({ ...state, data });
            }, 600);
          }),
        onRowDelete: oldData =>
          new Promise(resolve => {
            setTimeout(() => {
              resolve();
              const data = [...state.data];
              data.splice(data.indexOf(oldData), 1);
              setState({ ...state, data });
            }, 600);
          })
      }}
    />
  );
}

What am I doing wrong ?


Solution

  • React.useState() does not do a shallow merge as the setState method available in React.Component class

    setState((prevState) => ({
     ...prevState,
     data: result.data
    }))