【问题标题】:Use state variable in ag grid callback not updating在 ag 网格回调中使用状态变量不更新
【发布时间】:2020-02-21 22:59:52
【问题描述】:

我使用状态变量query,在函数isExternalFilterPresent 内部从不更新。我很困惑,因为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: []
};

编辑:更新了整个组件。

【问题讨论】:

  • 你能添加整个组件吗?
  • @AtinSingh 更新了整个组件。
  • 我将一个代码笔与一个简化的(只是一个虚拟的 AgGrid 组件)示例放在一起,该示例与钩子一起使用,但我看不出有什么问题。也许它仍然可以帮助您或其他人弄清楚working codepen欢呼!

标签: reactjs react-hooks ag-grid


【解决方案1】:

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

反应文档says:

useRef() Hook 不仅仅适用于 DOM 引用。 “ref”对象是一个通用容器,其当前属性是可变的并且可以保存任何值,类似于类上的实例属性。

所以你可能会想到 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上的一个例子

【讨论】:

  • 经过更多调查,我看到回调isExternalFilterPresent 永远不会更新,这意味着查询的值永远不会更新。使用 ref 是解决此问题的方法。感谢您的帮助!
猜你喜欢
  • 2021-05-02
  • 2019-04-05
  • 1970-01-01
  • 2021-08-09
  • 2020-01-15
  • 2020-04-11
  • 2017-09-26
  • 2020-11-13
  • 1970-01-01
相关资源
最近更新 更多