ag-Grid React 在设置 gridApi 后忘记了它 [英] ag-Grid React forgets gridApi after it has been set

查看:117
本文介绍了ag-Grid React 在设置 gridApi 后忘记了它的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我修改了

I have modified the Selection with Keys example to work with React. However as soon as I press an arrow key, the app crashes in the code below:

const [gridApi, setGridApi] = useState<GridApi | undefined>();

const handleGridReady = (event: GridReadyEvent) => {
  setGridApi(event.api);
  setGridColumnApi(event.columnApi);
};

const keyboardNavigation = (params: NavigateToNextCellParams): CellPosition => {
    if (gridApi === undefined) {
        throw new Error('This should never happen!');
    }
    ...
};

I am setting gridApi using onGridReady before any keys are pressed (confirmed by adding a console.log). So I don't know how it is getting undefined.

My full source code is here.

解决方案

const [gridApi, setGridApi] = React.useState<GridApi | undefined>();

const onGridReady = (params: GridReadyEvent) => {
  setGridApi(params.api);
  setGridColumnApi(params.columnApi);
};

console.log(gridApi); // log the latest gridApi instance if re-render

const keyboardNavigation = (
  params: NavigateToNextCellParams
): CellPosition => {
  // always reference the first instance of gridApi
  if (gridApi === undefined) {
    throw new Error("This should always happen!");
  }
  ...
}

This is commonly known as stale closure in react hook. From my understanding here is what happen:

  • Your callback keyboardNavigation is registered only once at the first render.
  • keyboardNavigation at that time references the gridApi instance from the very first render which is undefined.
  • AgGridReact in subsequent re-renders will use the first keyboardNavigation instance, thus references the same old gridApi even if it's been set now.

You can verify that by logging the gridApi in the render method, you can see from the second render, it has been initialized while your closure keyboardNavigation still references the stale instance of gridApi.

To fix that, you can change the code above to use reference instead of variable that can't be changed once baked in the closure.

type AgGridApi = {
  grid?: GridApi;
  column?: ColumnApi;
};

...

const apiRef = React.useRef<AgGridApi>({
  grid: undefined,
  column: undefined
});
const api = apiRef.current;
const onGridReady = (params: GridReadyEvent) => {
  apiRef.current.grid = params.api;
  apiRef.current.column = params.columnApi;
};

const yourCallback = () => {
  api.grid?.doSomething()
  api.column?.doSomething()
}

Live Demo

这篇关于ag-Grid React 在设置 gridApi 后忘记了它的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆