所以我已经在这个问题上停留了一段时间了。我将Devextreme用于React组件,我观察到一件事,当父组件的状态更改时,包含回调并使用该状态的子组件的props具有state的先前值。请考虑以下示例。
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回调将接收更新的值。有什么可能的解决方案可以避免useMemo。谢谢