Search code examples
javascriptreactjsmaterial-uireact-querymui-x-data-grid

How to update the @mui/x-data-grid table when data fetches


I have a question in terms of how data is updated in the DataGrid component from the @mui/x-data-grid module in React if anyone has experience with that Material UI library for displaying data in a table. The issue that I am having is in reference to updating the data in the table when an API fetch is completed. I am using react-query to fetch data from an API and am hoping to populate the table with this data. However, even after the fetch is complete, I still get the No rows message as you can see below in the table.

enter image description here

This does not make sense to me. As you can see in my console below, the data is fetching properly after the loading phase is completed in react-query. I am refetching the data every 1000 milliseconds just to emphasize the fact that this data is returning properly from the API. As you can see, an array of 3 objects is returning from the API to the Client as I would expect:

enter image description here

Here is the code process that I am going through:

First I created a hook with react-query to fetch this data from the API

export default function useFetchArtistSongs() {
    const { artist } = useUserData();
    const { _id } = artist;
    return useQuery(['fetchArtistSongs'], async () => {
        const artistSongsResponse = await axios({
            method: 'GET',
            url: `http://localhost:2000/api/get-artist-audio/${_id}`,
        }).then(response => {
            return response.data;
        });
        return artistSongsResponse;
    },  {
            refetchInterval: 3600000,
        },
    );
}

Next, I created a dataLayer within the component that renders the table so that I can pass the data property (list of objects) to the display layer that displays the table:

function useDataLayer() {
    const { data: artistSongs = [], isLoading } = useFetchArtistSongs();

    return {
        artistSongs,
        isLoading,
    };
}

I give the array of objects a default value to avoid an undefined error and I also get the isLoading property from the useQuery hook.

I finally pass the data to my component and then to the table:

function ClipsTableTest_DisplayLayer({
    artistSongs,
    isLoading,
}: ClipsTableDisplayLayerProps) {
    console.log(artistSongs);
    return (
        <ClipsTableContainer>
            <DataGrid 
                columns={columns}
                getRowId={(row: any) => row._id}
                loading={isLoading}
                rows={artistSongs}
                rowHeight={100}
                autoHeight
                autoPageSize
                disableColumnSelector
                disableRowSelectionOnClick
                hideFooterSelectedRowCount
            />
        </ClipsTableContainer>
    );
}

When I log the artistSongs array to the console it continuously updates and logs the data if I set the refetch rate to 1000 milliseconds. The catch in react-query is also updated. The table seems to be the only thing not getting the updated data.

I attempted to use a useEffect hook in order to set a state variable as the data updates and pass a state variable to the rows property of the DataGrid, but that failed too. I also tried useMemo with the same result. I even just straight up abandoned good programming structure and called fetched the data with axios directly in the display layer of this component -> updated the state variable once the response returned -> and the same No rows message appeared.

I am sorry if this was long-winded, but just wanted to be clear.


Solution

  • The issue here ended up being in the useFetchArtistSongs hook. When I return response.data this is just returning a tuple due to the way responses work in axios. I changed the return to:

    return response.data.artistAudio;
    

    instead of

    return response.data;
    

    and that resolved the problem.