I have components like below
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):
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. I want to render my child component when "props.data.values"
(type of this field is Array<string | number>
) changes. for that purpose I have created comparisonForRerender
function.
I am trying to compare props.data.value
in function like :(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.