在 ag 网格回调中使用状态变量不更新

Use state variable in ag grid callback not updating

我在函数 isExternalFilterPresent 内使用的状态变量 query 从不更新。我很困惑,因为 query 中的第一个 console.log 会随着查询的每次更改而更新。我想这是因为我不太了解hooks的实现。

let gridApi: GridApi | null = null;

const HouseholdTable = ({accountsData, aggregateEntityTable: {aggregateEntity, columnDefs}}: OwnProps & StateProps) => {

  const [isDeepDiveOpen, setIsDeepDiveOpen] = useState(false);
  const [query, setQuery] = useState('');

  useEffect(() => {
    gridApi && gridApi.onFilterChanged();
  }, [query]);

  if (accountsData) {

    const onGridReady = ({api}: GridReadyEvent) => {
      api.sizeColumnsToFit();
      gridApi = api;
    };

    const aggData = accountsData.aggregations[aggregateEntity];

    console.log(query); // This updates when query changes
    const isExternalFilterPresent = (): boolean => {
      console.log(query); // This never updates
      return !!query; 
    };

    const doesExternalFilterPass = (rowNode: RowNode): boolean => {
      // console.log('doesExternalFilterPass');
      return true;
    };

    return (
      <>
        <HouseholdsToolbar aggData={aggData}
          isDeepDiveOpen={isDeepDiveOpen}
          onDeepDiveToggleClick={setIsDeepDiveOpen}
          onQueryChange={setQuery}
        />
        <AgGridReact rowData={[]}
          columnDefs={[]}
          gridOptions={{
            headerHeight: 70,
            suppressFieldDotNotation: true,
            suppressHorizontalScroll: false,
            onGridReady,
            isExternalFilterPresent,
            doesExternalFilterPass
          }}
        />
      </>
    );
  } else {
    // handle loading
    return (<div>loading</div>);
  }
};

const mapStateToProps = (state: StoreState): StateProps => {
  const {faStore: {accountsData}} = state;
  return {
    accountsData,
    aggregateEntityTable: aggregateEntityTableDummyConfig
  };
};

export default connect(mapStateToProps)(HouseholdTable);

export const aggregateEntityTableDummyConfig: AggregateEntityTable = {
  aggregateEntity: 'FOO',
  columnDefs: []
};

编辑:更新了整个组件。

不是钩子的问题。看起来在第一次渲染时 AgGridReact 存储了对传递给 isExternalFilterPresent 的函数的引用,然后在重新渲染时永远不会更改此引用。更清楚地说,AgGridReact 存储 isExternalFilterPresent 的第一个 'version' 并且从不更新它。要解决您的问题,您需要将过滤器的值存储在 useRef 挂钩中。

React 文档 says:

The useRef() Hook isn’t just for DOM refs. The “ref” object is a generic container whose current property is mutable and can hold any value, similar to an instance property on a class.

因此您可能会像 class 中的 属性 一样考虑 useRef。

这是你必须做的:

const query = useRef(null);

const setQuery = (value) => {
  query.current = value;
  gridApi && gridApi.onFilterChanged();
}

const isExternalFilterPresent = (): boolean => {
  console.log(query.current); // Now it changes
  return !!query.current; 
};

这里有一个关于 codesandbox

的例子