简体   繁体   English

React Memo 更新父组件状态

[英]React Memo updating Parent component state

I have components like below我有如下组件

QuestionAnsPage.component(parent) : 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]);
.
.
..
}

My QuestionAnswer.componet(child):我的 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);

I am using this React.memo for performance improvement.我正在使用这个React.memo来提高性能。 I want to render my child component when "props.data.values" (type of this field is Array<string | number> ) changes.我想在"props.data.values" (此字段的类型为Array<string | number> )更改时呈现我的子组件。 for that purpose I have created comparisonForRerender function.为此,我创建了comparisonForRerender函数。

I am trying to compare props.data.value in function like : (prevValArr.includes(nextValArr[0]))我正在尝试比较props.data.value中的函数: (prevValArr.includes(nextValArr[0]))

But this function causing some weird behavior, my parent component state get reset to old value some how(data in this case).但是这个函数导致了一些奇怪的行为,我的父组件状态以某种方式重置为旧值(在这种情况下为数据)。

I am not sure but this comparison function somehow changing my parent component state.我不确定但是这个比较函数以某种方式改变了我的父组件状态。 If I remove this function then it is working fine.如果我删除此功能,则它工作正常。

Your parent component is being updated because props.data is an array.您的父组件正在更新,因为props.data是一个数组。 Only the pointer of the array is checked in the dependency array, of the useEffect function, you'll need to compare value of every element in the array, or choose a different a dependency variable, maybe something like the length of the array.在依赖数组中只检查数组的指针,在useEffect函数中,您需要比较数组中每个元素的值,或者选择不同的依赖变量,可能类似于数组的长度。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM