英文:
How to use the MUI X DataGrid API in a TypeScript application that is not fully React based
问题
我需要在一个 TypeScript 网页应用中使用 MUI X DatGrid,该应用不是完全基于 React,有时只使用独立的 React 组件。
以下是如何创建一个功能性 API 的原型示例代码。
想法是使用 GridApi 与网格组件进行功能性交互,但代码看起来相当混乱,我在思考:
- 是否有更聪明的方法来做这个?
- 为什么需要在检索 GridApi 之前使用 setTimeout?
- 是否有一种方法可以在不更改任何属性的情况下强制 DataGrid 刷新?
import * as React from 'react';
import ReactDOM from 'react-dom/client';
import { StyledEngineProvider } from '@mui/material/styles';
import { DataGrid, useGridApiRef } from '@mui/x-data-grid';
import type { GridApi } from '@mui/x-data-grid';
export type apiRefType = React.MutableRefObject<GridApi>;
type GridPropsType = {
hideFooter: boolean,
setApiRef: (ref: apiRefType) => void,
};
const Grid = ({ setApiRef }: GridPropsType): JSX.Element => {
const apiRef = useGridApiRef();
setApiRef(apiRef);
return (
<React.StrictMode>
<StyledEngineProvider injectFirst>
<div style={{ height: '100%', width: '100%' }}>
<DataGrid columns={[]} rows={[]} apiRef={apiRef} />
</div>
</StyledEngineProvider>
</React.StrictMode>
);
};
export const renderGrid = async (target: HTMLElement, hideFooter: boolean): Promise<apiRefType> => {
let apiRef: apiRefType | null = null;
const setApiRef = (ref: apiRefType): void => {
apiRef = ref;
};
return new Promise((resolve) => { // eslint-disable-line promise/avoid-new
ReactDOM.createRoot(target).render(<Grid hideFooter={hideFooter} setApiRef={setApiRef} />);
setTimeout(() => {
if (apiRef === null) {
throw new Error('apiref was not initialized');
}
resolve(apiRef);
}, 0);
});
};
英文:
I need to use the MUI X DatGrid in a TypeScript web application that is not fully react based but sometimes only uses individual React components.
The following example code shows a prototype on how to create a functional API.
The idea is to use the GridApi to functionally interact with the grid component but the code seems pretty ugly and I'm wondering:
- is there a smarter way to do this?
- why do i need the setTimeout before I can retrieve the
GridApi
? - is there a way to force the DataGrid to refresh without changing any properties?
import * as React from 'react';
import ReactDOM from 'react-dom/client';
import {StyledEngineProvider} from '@mui/material/styles';
import {DataGrid, useGridApiRef} from '@mui/x-data-grid';
import type {GridApi} from '@mui/x-data-grid';
export type apiRefType = React.MutableRefObject<GridApi>;
type GridPropsType = {
hideFooter: boolean,
setApiRef: (ref: apiRefType) => void,
};
const Grid = ({setApiRef}: GridPropsType): JSX.Element => {
const apiRef = useGridApiRef();
setApiRef(apiRef);
return (
<React.StrictMode>
<StyledEngineProvider injectFirst>
<div style={{height: '100%', width: '100%'}}>
<DataGrid columns={[]} rows={[]}apiRef={apiRef} />
</div>
</StyledEngineProvider>
</React.StrictMode>
);
};
export const renderGrid = async (target: HTMLElement, hideFooter: boolean): Promise<apiRefType> => {
let apiRef: apiRefType | null = null;
const setApiRef = (ref: apiRefType): void => {
apiRef = ref;
};
return new Promise((resolve) => { // eslint-disable-line promise/avoid-new
ReactDOM.createRoot(target).render(<Grid hideFooter={hideFooter} setApiRef={setApiRef}/>);
setTimeout(() => {
if (apiRef === null) {
throw new Error('apiref was not initialized');
}
resolve(apiRef);
}, 0);
});
};
答案1
得分: -1
Olivier Tassinari在这个SR中提供了一个出色的解决方案。
import { renderGrid } from "./demo";
const cols = [{ field: "username" }, { field: "age" }];
const rows = [{ id: 1, username: "@MUI", age: 20 }];
(async () => {
const target = document.getElementById("root");
const gridApi = await renderGrid(target, {
hideFooter: true
});
gridApi.current.updateColumns(cols);
gridApi.current.updateRows(rows);
})();
import * as React from "react";
import * as ReactDOM from "react-dom/client";
import { StyledEngineProvider } from "@mui/material/styles";
import { DataGrid, DataGridProps, useGridApiRef, GridApi } from "@mui/x-data-grid";
type Optional<T, K extends keyof T> = Pick<Partial<T>, K> & Omit<T, K>;
export type apiRefType = React.MutableRefObject<GridApi>;
type GridPropsType = {
options: Optional<DataGridProps, "rows" | "columns">;
setApiRef: (ref: apiRefType) => void;
};
const Grid = ({ setApiRef, options }: GridPropsType): JSX.Element => {
const apiRef = useGridApiRef();
React.useLayoutEffect(() => {
setApiRef(apiRef);
}, [setApiRef, apiRef]);
return (
<React.StrictMode>
<StyledEngineProvider injectFirst>
<div style={{ height: "100%", width: "100%" }}>
<DataGrid columns={[]} rows={[]} apiRef={apiRef} {...options} />
</div>
</StyledEngineProvider>
</React.StrictMode>
);
};
export const renderGrid = async (
target: HTMLElement,
options: GridPropsType["options"]
): Promise<apiRefType> => {
return new Promise((resolve) => {
// eslint-disable-line promise/avoid-new
ReactDOM.createRoot(target).render(
<Grid options={options} setApiRef={resolve} />
);
});
};
英文:
Olivier Tassinari offers an excellent solution in this SR
import { renderGrid } from "./demo";
const cols = [{ field: "username" }, { field: "age" }];
const rows = [{ id: 1, username: "@MUI", age: 20 }];
(async () => {
const target = document.getElementById("root");
const gridApi = await renderGrid(target, {
hideFooter: true
});
gridApi.current.updateColumns(cols);
gridApi.current.updateRows(rows);
})();
import * as React from "react";
import * as ReactDOM from "react-dom/client";
import { StyledEngineProvider } from "@mui/material/styles";
import { DataGrid, DataGridProps, useGridApiRef, GridApi } from "@mui/x-data-grid";
type Optional<T, K extends keyof T> = Pick<Partial<T>, K> & Omit<T, K>;
export type apiRefType = React.MutableRefObject<GridApi>;
type GridPropsType = {
options: Optional<DataGridProps, "rows" | "columns">;
setApiRef: (ref: apiRefType) => void;
};
const Grid = ({ setApiRef, options }: GridPropsType): JSX.Element => {
const apiRef = useGridApiRef();
React.useLayoutEffect(() => {
setApiRef(apiRef);
}, [setApiRef, apiRef]);
return (
<React.StrictMode>
<StyledEngineProvider injectFirst>
<div style={{ height: "100%", width: "100%" }}>
<DataGrid columns={[]} rows={[]} apiRef={apiRef} {...options} />
</div>
</StyledEngineProvider>
</React.StrictMode>
);
};
export const renderGrid = async (
target: HTMLElement,
options: GridPropsType["options"]
): Promise<apiRefType> => {
return new Promise((resolve) => {
// eslint-disable-line promise/avoid-new
ReactDOM.createRoot(target).render(
<Grid options={options} setApiRef={resolve} />
);
});
};
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论