mui / mui-x

MUI X: Build complex and data-rich applications using a growing list of advanced React components, like the Data Grid, Date and Time Pickers, Charts, and more!
https://mui.com/x/
3.92k stars 1.19k forks source link

[DataGrid] The `forceUpdate` API does not seem to force an update of the grid #9722

Closed doberkofler closed 11 months ago

doberkofler commented 11 months ago

Duplicates

Latest version

Steps to reproduce πŸ•Ή

Link to live example: https://codesandbox.io/s/intelligent-cache-gk2zzz?file=/demo.tsx:0-1631

Step 1: run the example Step 2: click on the "Set color" button to set the background color of all rows to red

Current behavior 😯

The given example shows a use case where the forceUpdate API is used to force the grid to update but it does not seem to do so. When using useState to manage the rowClasses object the example works as expected because changing the state automatically forces the component to update. I would expect forceUpdate to trigger a manual update of the grid component but this does not seem to be the case.

import * as React from "react";
import Button from "@mui/material/Button";
import Stack from "@mui/material/Stack";
import Box from "@mui/material/Box";
import { DataGrid, useGridApiRef } from "@mui/x-data-grid";
import { useDemoData } from "@mui/x-data-grid-generator";
import type { GridRowClassNameParams } from "@mui/x-data-grid";

import "./demo.css";

const rowClasses = {};

export default function UseGridApiRef() {
  const { data } = useDemoData({
    dataSet: "Commodity",
    rowLength: 10,
    maxColumns: 6
  });
  /*    NOTE: when using state it does work as expected
    const [rowClasses, setRowClasses] = React.useState({});
    */

  const apiRef = useGridApiRef();

  const handleSetColor = () => {
    data.rows.forEach((e) => (rowClasses[e.id] = "rowRed"));
    apiRef.current.forceUpdate();

    /*
    const newRowClasses = {};
    data.rows.forEach((e) => {
      newRowClasses[e.id] = "rowRed";
    });
        setRowClasses(newRowClasses);
        */
  };

  const handleClearColor = () => {
    for (const key in rowClasses) {
      delete rowClasses[key];
    }
    apiRef.current.forceUpdate();

    /*
        setRowClasses({});
        */
  };

  return (
    <Stack spacing={1} sx={{ width: "100%" }} alignItems="flex-start">
      <Button onClick={handleSetColor}>Set color</Button>
      <Button onClick={handleClearColor}>Clear color</Button>
      <Box sx={{ height: 600, width: "100%" }}>
        <DataGrid
          {...data}
          getRowClassName={(params: GridRowClassNameParams) =>
            rowClasses[params.id]
          }
          hideFooter
          apiRef={apiRef}
        />
      </Box>
    </Stack>
  );
}

Expected behavior πŸ€”

I would expect the grid component to update when the forceUpdate API is used

Context πŸ”¦

No response

Your environment 🌎

npx @mui/envinfo ``` System: OS: macOS 13.4.1 Binaries: Node: 18.16.1 - ~/.nvm/versions/node/v18.16.1/bin/node Yarn: Not Found npm: 9.8.0 - ~/.nvm/versions/node/v18.16.1/bin/npm Browsers: Chrome: 114.0.5735.198 npmPackages: @emotion/react: 11.10. => 11.11.1 @emotion/styled: 11.11.0 => 11.11.0 @mui/base: 5.0.0-beta.7 @mui/core-downloads-tracker: 5.14.0 @mui/icons-material: 5.14.0 => 5.14.0 @mui/material: 5.14.0 => 5.14.0 @mui/private-theming: 5.13.7 @mui/styled-engine: 5.13.2 @mui/system: 5.14.0 @mui/types: 7.2.4 @mui/utils: 5.13.7 @mui/x-data-grid: 6.10.0 @mui/x-data-grid-pro: 6.10.0 => 6.10.0 @mui/x-license-pro: 6.10.0 @types/react: 18.2.15 => 18.2.15 react: 18.2.0 => 18.2.0 react-dom: 18.2.0 => 18.2.0 typescript: 5.1.6 => 5.1.6 ```

Order ID or Support key πŸ’³ (optional)

No response

romgrk commented 11 months ago

You should be using normal React state, like you note in your comment.

doberkofler commented 11 months ago

@romgrk Sure, but in my specific use case it is difficult to use React state and that's why I'm looking for alternatives. I nevertheless would like to understand why my example is not working and what the exact functionality of the forceUpdate API in the DataGrid is?

romgrk commented 11 months ago

forceUpdate is going to be deprecated and by default shouldn't be used by external code. If you have a specific problem with React state you can open a ticket for that.