При использовании функционального компонента реквизиты дочернего компонента не обновляются при изменении состояния родительского компонента - PullRequest
0 голосов
/ 03 апреля 2020

Так что я застрял в этой проблеме на некоторое время. Я использую компоненты Devextreme для React и заметил, что при изменении состояния родительского компонента реквизиты дочернего компонента, содержащие обратные вызовы и потребляющие состояние, имеют предыдущее значение состояния. Рассмотрим следующий пример.

import merge from 'lodash/merge';
import React, {
  ReactElement, useLayoutEffect, useState, useMemo
} from 'react';
import { ITreeListOptions } from 'devextreme-react/tree-list';
import {
  IPropertyValidatorReturnType,
  validateProperty,
  InvalidRecordError,
} from '@intech-apps/platform';
import { notify } from '../../../utils';
import { IBaseGridModel } from '../../../../core';

import {
  renderOptionalGridColumns,
  replaceQuotesAndStringify,
  isLocationProperty,
  isSpatialLocationProperty,
  isLocationRow,
  isSpatialLocationRow,
} from '../actions';

import { DataGrid } from '../data-grid';
import { usePropertyType } from '../../../hooks';
import { propertyTypeFragment } from '../../../fragments';
interface IDataGridProps<T> extends ITreeListOptions {
  onChange?: (data: T[]) => void;
  gridData?: T[];
  setGridData?: (data: T[]) => void; // optional prop for read-only grids
}

export function PropertyGrid<TModel extends IBaseGridModel<TModel>>(
  props: IDataGridProps<TModel>,
): ReactElement {

  const [defaultProperty, setDefaultProperty] = useState();
  const { getAll: getDefaultProperty } = usePropertyType();

  useLayoutEffect(() => {
    if (!defaultProperty) {
      Promise.resolve(getDefaultProperty(
        propertyTypeFragment, { where: { code: 'string_property' } }
      )).then((data) => {
        if (data.length > 1) throw new InvalidRecordError()
        setDefaultProperty(data[0])
      })
    }
  })

  const propertyGridProps: ITreeListOptions = {

    onInitNewRow: (e) => {
      e.data.propertyType = defaultProperty;
      renderOptionalGridColumns(e.component, defaultProperty);
    },

    onEditingStart: e => {
      renderOptionalGridColumns(e.component, e.data.propertyType);
    },
    ...props,
  };
  return <DataGrid {...propertyGridProps} />;
}

В этом примере выше onInitNewRow всегда получает старое значение состояния, которое в этом случае не определено. Далее, отладив, я обнаружил, что если я использую useMemo и перенесу в него propertyGridProps, обратный вызов onInitNewRow получит обновленное значение. Есть ли возможное решение, где я могу избежать использования Memo. Спасибо

...