1

我有如下组件

QuestionAnsPage.component(parent)

export interface FieldsDatatype {
  id: string | number;
  attributeId: string | number,
  mainQuestionFlg?: boolean;
  mainQuestionId: number | string,
  question: string;
  **values: Array<number | string>;**
  fieldType: number;
  mandatory: boolean;
  isNumber: boolean;
  pattern?: string;
  max?: string | number;
  min?: string | number;
  displayInline?: boolean;
  error?: boolean;
  message?: string;
  options: OptionsType[] | undefined | null;
  storedColumn?: string;
  storedJson?: string;
}

type Props = {
  data?: FieldsDatatype[];
  country: string;
  handleOnConfirmClick: (data: FieldsDatatype[]) => void;
  handleOnCancelClick: () => void;
  isLoading?: boolean;
  errorMessage?: Error;
  id: string | number;
}
const QuestionAnsPageComponent = (props: Props): JSX.Element => {
    const [data, setData] = useState([]);
    
    useEffect(() => {
        if (props.data) {
          setData(props.data);
        }
      }, [props.data]);
.
.
..
}

我的 QuestionAnswer.componet(child):

type Props = {
  data: FieldsDatatype;
  onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void;
  onChangeSelect?: (id: string | number, value: string | number) => void;
  onDateChange?: (fieldName: string | number, value: string) => void;
  onBlur?: (event: React.FocusEvent<HTMLInputElement | HTMLButtonElement | HTMLTextAreaElement>) => void;
  country: string;
}

   const QuestionAnswerComponent = (props: Props): JSX.Element => {
    function comparisonForRerender(prevProps: Props, nextProps: Props): boolean {
         console.log('nextProps:', nextProps.data.values, nextProps.data.id);
         console.log('prevProps:', prevProps.data.values, prevProps.data.id);
      const nextValArr = [...nextProps.data.values];
      const prevValArr = prevProps.data ? [...prevProps.data.values] : [];
      const nextValuesLen = nextValArr.length;
      const prevValuesLen = prevValArr.length;
      if (nextValArr
        && prevValArr
        && nextValuesLen > 1
        && nextProps.data.fieldType === FIELDS_TYPE.CHECKBOX) {
        return (nextValuesLen === prevValuesLen
              && JSON.stringify(prevValArr) === JSON.stringify(prevValArr));
      } else if (nextValArr
        && prevValArr
        && nextValuesLen > 0
        && prevValuesLen > 0
        && nextProps.data.id === prevProps.data.id) {
        **return (prevValArr.includes(nextValArr[0]));**
      }
      return false;
    }
    }

    export default React.memo(QuestionAnswerComponent, comparisonForRerender);

我正在使用它React.memo来提高性能。我想在"props.data.values"(此字段的类型为Array<string | number>)更改时呈现我的子组件。为此,我创建了comparisonForRerender函数。

我正在尝试比较props.data.value功能,例如:(prevValArr.includes(nextValArr[0]))

但是这个函数会导致一些奇怪的行为,我的父组件状态会以某种方式重置为旧值(在这种情况下是数据)。

我不确定,但这个比较函数以某种方式改变了我的父组件状态。如果我删除此功能,那么它工作正常。

4

1 回答 1

0

您的父组件正在更新,因为props.data它是一个数组。在函数的依赖数组中只检查数组的指针useEffect,你需要比较数组中每个元素的值,或者选择一个不同的依赖变量,比如数组的长度。

于 2020-09-17T11:13:31.260 回答