Использовать переменную состояния в обратном вызове сетки ag не обновляется - PullRequest
1 голос
/ 25 октября 2019

Моя переменная состояния использования, query, внутри функции isExternalFilterPresent никогда не обновляется. Я озадачен, потому что первые console.log из query обновляются при каждом изменении запроса. Я думаю, что это потому, что я не совсем понимаю реализацию хуков.

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: []
};

РЕДАКТИРОВАТЬ: Обновлено со всем компонентом.

1 Ответ

1 голос
/ 25 октября 2019

Это не проблема с крючками. Похоже, что при первом рендеринге AgGridReact сохраняет ссылку на функцию, которую вы передаете isExternalFilterPresent, и затем никогда не изменяет эту ссылку при повторном рендеринге. Чтобы быть более понятным, AgGridReact хранит первую «версию» isExternalFilterPresent и никогда не обновляет ее. Чтобы решить вашу проблему, вам нужно сохранить значение вашего фильтра в useRef hook.

React doc говорит :

Хук useRef ()не только для рефери 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

...