简体   繁体   English

ag-Grid React 在设置 gridApi 后忘记了它

[英]ag-Grid React forgets gridApi after it has been set

I have modified the Selection with Keys example to work with React.我已经修改了带有键选择示例以与 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 ).我在按下任何键之前使用onGridReady设置gridApi (通过添加console.log确认)。 So I don't know how it is getting undefined .所以我不知道它是如何变得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仅在第一次渲染时注册一次。
  • keyboardNavigation at that time references the gridApi instance from the very first render which is undefined .那时的keyboardNavigation gridApi undefined第一个渲染中引用了gridApi实例。
  • AgGridReact in subsequent re-renders will use the first keyboardNavigation instance, thus references the same old gridApi even if it's been set now. AgGridReact在随后的重新渲染中将使用第一个keyboardNavigation实例,因此即使现在已经设置,也会引用相同的旧gridApi

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 .您可以通过在 render 方法中记录gridApi来验证,您可以从第二次渲染中看到,它已被初始化,而您的闭包keyboardNavigation仍然引用了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现场演示

编辑 64071586/ag-grid-react-forgets-gridapi-after-it-has-been-set

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM