javascriptreactjsmaterial-uimui-x-data-grid

renderCell from Mui DataGrid not rendering conditionally


I have a simple setup for my Mui DataGrid. The issue I have though, is that renderCell isn't rendering my elements conditionally.

enter image description here

It should show per default an EditIcon button (the pencil) and as soon as I click on it, it should call fetchSomething - which it does - and switch to the Mui CircularProgress element by setting isLoading to true but the CircularProgress element is never displayed.

I tested quickly via a useEffect to see if the state changes and it does change from false to true then again to false but the CircularProgress is nowhere to be seen.

Am I having issues with ids? Any way to solve this?

const Component = () => {
    const [isLoading, setIsLoading] = useState(false);

    const fetchSomething = (event) => {

        setIsLoading(true);

        fetch(event.id)
         .then(() => doSmth())
         .catch((error) => console.log(error))
         .finally(() => setIsLoading(false));
    };


    const usersTableColumns = [
            {
                field: 'id',
                headerName: 'ID',
                width: 200,
                flex: 1,
            },
            {
                field: 'username',
                headerName: 'USER NAME',
                width: 170,
                flex: 1,
            },
            {
                field: 'action',
                headerName: 'Edit',
                sortable: false,
                renderCell: (params) => (isLoading ? <CircularProgress size={30} /> : (
                    <EditIcon onClick={fetchSomething} />
                )),
            },
    ];

    return(
        <DataGrid rows={rows} columns={usersTableColumns}/>
    );
}

EDIT According to the logic above all pencils should become spinners as soon as I click on one of them, so I tried adding dynamically the ids to the state and checking for a certain id when displaying CircularProgress but it seems like the state updates just don't show up for renderCell.


Solution

  • For anyone struggling with this the solution is very simple. It took me a bit but I got it.

    You need to export the content of renderCell into a new component and import it. You will also have to put the hook into that component. This will create a component for each row so you will not have any issues with ids.

    Even then, conditionally rendering the cell would not work anyways.

    enter image description here

    https://mui.com/x/react-data-grid/column-definition/

    const Component = ({
        fetchSmth, params,
    }) => {
        const [isLoading, setIsLoading] = useState(false);
    
        const doSmth= async () => {
            setIsLoading(true);
            await fetchSmth(params.row);
            setIsLoading(false);
        };
    
        return (
            <Tooltip title='Some title'>
                <IconButton
                    variant='contained'
                    onClick={(e) => {
                        doSmth(e);
                    }}
                >
                    {isLoading ? <CircularProgress size={30} /> : <EditIcon />}
                </IconButton>
            </Tooltip>
        );
    };
    
    export default Component;
    

    renderCell has just to render this component. You can test this (if your REST call is too fast by throttling your browser in mobile mode.