给ref.current赋值时运行useEffect

时间:2020-06-24 09:29:09

标签: reactjs react-hooks use-effect ag-grid-react

我有一个父组件,该子组件具有一个子组件,我将通过prop将引用转发到该子组件。子组件包含一个ag-grid组件,该组件为我提供了一个API,我将通过转发的ref将其发送给父组件,如下所示:

import React, { useRef } from "react";
import { AgGridReact } from "ag-grid-react";

function Parent() {
  const defaultFilter = {
    transactionId: {
      filterType: "number",
      type: "equals",
      filter: 1111
    }
  }

  const gridApi = useRef();

  useEffect(() => {
    gridApi.current.setFilterModel(defaultFilter); // <== throws error: TypeError: Cannot read property 'setFilterModel' of undefined
  }, [])

  return (
    <div>
      <MyGrid forwardedRef={gridApi} />
    </div>
  );
}

function MyGrid(props) {
  const gridApi = useRef();

  const onGridReady = params => {
    gridApi.current = params.api;

    if (props.forwardedRef) {
      props.forwardedRef.current = params.api; // <== send grid's api to parent ref
    }

    ...
  };

  ...

  return (
    <div>
      <AgGridReact
        reactNext={true}
        onCellValueChanged={onCellValueChanged}
        onGridReady={onGridReady}
        columnDefs={columnDefs}
        pagination={true}
        context={ref}
        onSelectionChanged={onRowSelect}
        {...options}
      ></AgGridReact>
    </div>
  );
}

有很多代码,因此我省略了其中的一些以重点讨论此问题。

现在,如您在上面的代码中看到的,我正在尝试为ag-grid组件中的Child设置过滤器。我想在组件安装在页面上后立即设置过滤器。但这会引发错误,gridApi.current中的useEffectundefined

如何解决此问题?

1 个答案:

答案 0 :(得分:0)

您必须等待onGridReady才能调用gridApi.current.setFilterModel(defaultFilter)。然后,只有您将具有未定义的gridApi.current。 因此,与其在useEffect中运行gridApi.current.setFilterModel(defaultFilter);,不如将它放在Parent的回调中,然后将该回调传递给子MyGrid

示例代码:-

function Parent() {
  const defaultFilter = {
    transactionId: {
      filterType: "number",
      type: "equals",
      filter: 1111
    }
  }

  const gridApi = useRef();

  const setParentFilterModel = () => { // <== callback function to be called on onGridReady
    gridApi.current.setFilterModel(defaultFilter); 
  };

  return (
    <div>
      <MyGrid forwardedRef={gridApi} setParentFilterModel={setParentFilterModel}/> {/* <== pass callback function  to child */}
    </div>
  );
}

function MyGrid(props) {
  const gridApi = useRef();

  const onGridReady = params => {
    gridApi.current = params.api;

    if (props.forwardedRef) {
      props.forwardedRef.current = params.api; 
      props.setParentFilterModel() // <== call callback function
    }

  };
}