React Memo обновляет состояние родительского компонента
У меня есть такие компоненты, как показано ниже
QuestionAnsPage.component(родительский)
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(ребенок)
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
Я пытаюсь сравнить props.data.value в функции, например:(prevValArr.includes(nextValArr[0]))
Но эта функция вызывает какое-то странное поведение, состояние моего родительского компонента каким-то образом сбрасывается до старого значения (в данном случае данные).
Я не уверен, но эта функция сравнения каким-то образом меняет состояние моего родительского компонента. Если я удалю эту функцию, она будет работать нормально.
1 ответ
Ваш родительский компонент обновляется, потому что
props.data
это массив. В массиве зависимостей проверяется только указатель на массив.
useEffect
функции, вам нужно будет сравнить значение каждого элемента в массиве или выбрать другую переменную зависимости, возможно, что-то вроде длины массива.