ag-Grid React, gridApi ayarlandıktan sonra unutur

Sep 25 2020

Ben değiştirdiniz Tuşlar ile Seçimi Tepki ile çalışmalarına örnek. Ancak bir ok tuşuna basar basmaz, uygulama aşağıdaki kodda çöküyor:

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!');
    }
    ...
};

Herhangi bir tuşa basılmadan önce gridApikullanmayı ayarlıyorum onGridReady(a ekleyerek onaylayın console.log). O yüzden nasıl oluyor bilmiyorum undefined.

Tam kaynak kodum burada .

Yanıtlar

2 NearHuscarl Sep 26 2020 at 04:43
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!");
  }
  ...
}

Bu genellikle reaksiyon kancasında bayat kapanma olarak bilinir . Anladığım kadarıyla burada olan şey:

  • Geri aramanız keyboardNavigationilk işlemede yalnızca bir kez kaydedilir.
  • keyboardNavigationo anda gridApiilk renderdan gelen örneğe başvurur undefined.
  • AgGridReactsonraki yeniden işlemelerde ilk keyboardNavigationörneği kullanır, bu nedenle şimdi ayarlanmış olsa bile aynı eskiye gridApi başvurur.

gridApiOluşturma yöntemini günlüğe kaydederek, ikinci işlemeden başlayarak, kapanışınız keyboardNavigation hala eski örneğine başvururken başlatıldığını görebilirsiniz gridApi.

Bunu düzeltmek için, yukarıdaki kodu, kapanışta pişirildikten sonra değiştirilemeyen değişken yerine referans kullanacak şekilde değiştirebilirsiniz.

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()
}

Canlı Demo