在 ag 网格回调中使用状态变量未更新 [英] Use state variable in ag grid callback not updating

查看:18
本文介绍了在 ag 网格回调中使用状态变量未更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

let gridApi: GridApi |空 = 空;const HouseholdTable = ({accountsData, aggregateEntityTable: {aggregateEntity, columnDefs}}: OwnProps & StateProps) =>{const [isDeepDiveOpen, setIsDeepDiveOpen] = useState(false);const [查询,setQuery] = useState('');useEffect(() => {gridApi &&gridApi.onFilterChanged();}, [询问]);如果(帐户数据){const onGridReady = ({api}: GridReadyEvent) =>{api.sizeColumnsToFit();gridApi = api;};const aggData = accountsData.aggregations[aggregateEntity];控制台日志(查询);//当查询改变时更新const isExternalFilterPresent = (): boolean =>{控制台日志(查询);//这永远不会更新返回!!查询;};const doExternalFilterPass = (rowNode: RowNode): boolean =>{//console.log('doesExternalFilterPass');返回真;};返回 (<><HouseholdsToolbar aggData={aggData}isDeepDiveOpen={isDeepDiveOpen}onDeepDiveToggleClick={setIsDeepDiveOpen}onQueryChange={setQuery}/><AgGridReact rowData={[]}columnDefs={[]}网格选项={{标头高度:70,抑制FieldDotNotation:真,抑制水平滚动:假,onGridReady,isExternalFilterPresent,外部过滤器通过}}/></>);} 别的 {//处理加载返回(<div>加载</div>);}};const mapStateToProps = (state: StoreState): StateProps =>{const {faStore: {accountsData}} = 状态;返回 {帐户数据,聚合实体表:聚合实体表虚拟配置};};导出默认连接(mapStateToProps)(HouseholdTable);导出 constaggregateEntityTableDummyConfig:AggregateEntityTable = {聚合实体:'FOO',列定义:[]};

更新了整个组件.

解决方案

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

React 文档 :

<块引用>

useRef() 钩子不仅仅用于 DOM 引用.ref"对象是一个通用容器,其当前属性是可变的,可以保存任何值,类似于类的实例属性.

所以你可能会认为 useRef 就像类中的属性一样.

这是你必须做的:

const query = useRef(null);const setQuery = (value) =>{query.current = 值;gridApi &&gridApi.onFilterChanged();}const isExternalFilterPresent = (): boolean =>{控制台日志(查询.当前);//现在变了返回 !!query.current;};

这里有一个关于 codesandbox

My use state variable, query, inside of the function isExternalFilterPresent never updates. I'm perplexed because the first console.log of query updates with each change of query. I think this is because I'm not quite understand the implementation of 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: []
};

EDIT: Updated with the entire component.

解决方案

It is not a problem with hooks. It looks like on the first rendering AgGridReact stores the reference to a function that you pass to isExternalFilterPresent and then never changes this reference on re-renders. To be more clear, AgGridReact stores the first 'version' of isExternalFilterPresent and never updates it. To fix your problem, you need to store the value of your filter in useRef hook.

React doc 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.

So you might think about useRef like about property in the class.

Here what you have to do:

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; 
};

Here an example on codesandbox

这篇关于在 ag 网格回调中使用状态变量未更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆