[문제점]
자식요소에서 부모요소에서 상태관리 중인 배열을 참조하고 있고,
배열의 상태 조작 시(값 변경 시),
해당 상태를 참조하고 있는 자식 요소 전체가 불필요하게 리렌더링 되는 상황이 발생함.
(해당 원소를 참조하는 카드만 리렌더링되어야 함)
예)
const ParentComponent = () => {
const [list, setList] = usetate()
// list의 원소 하나만 바뀌어도 모든 ChildrenCard가 리렌더링 됨.
return (
<>
{storeData.map((v: any, i: any) => (
<ChildrenCard data={list[i]} />
)}
</>
)
}
[탐구과정]
1. Chat GPT에게 열심히 물어봤는데, 리액트는 값의 변화를 감지하기 때문에 배열이 변경되어도 해당 값을 참조하는 해당 컴포넌트만 변경된다고 주야장천 얘기함.... 이로 시간 허비 많이 함.
=> 하지만 결과는 다름. 예를 들어 카드가 10개면, 배열의 모든 값이 한차례 변경되면 10 * 10, = 100회의 리렌더링이 발생함.
2. React.memo() 사용
=> 자식요소를 memo로 저장해두고, 항상성을 유지해야 하는 함수를 해당 (prev, next) => prev.data === next.data 로 설정.
=> 하지만 어차피 부모요소 단에서 '전체가 변경되었음'의 신호를 전파해 버리니 전혀 먹히지 않음^^
[해결방안]
1. 상태가 아닌 일반 변수를 useRef로 관리
set 함수 없이, javaScript 코드로 속성 적용
const ParentComponent = () => {
// useState 대신 useRef로 관리
cosnt list = useRef<string[]>([]);
useEffect(()=>{
if(someFactor){
//javaScript 코드로 속성 적용
const img = document.getElementById(`storeCard_${storeIdx}`) as HTMLImageElement | null;
if(img){
img.src = list[0];
}
}
}, [someFactor])
return (
<>
{storeData.map((v: any, i: any) => (
<ChildrenCard />
)}
</>
)
}
2. 자식 요소 내부에서 상태관리를 하고 업데이트 함.
=> 애초에 필요한 데이터를 모두 내부에서 선언하고, 필요한 useEffect도 모두 내부러 가져감.
const ParentComponent = () => {
const GetChildrens = () => {
const [list, setList] = usetate()
useEffect(()=>{
if (someFactor) {
setList(newArr)
}
}, [someFactor])
return(
<>
{storeData.map((v: any, i: any) => (
<ChildreComponent aa={v.aa] bb={v.bb}/>
)}
</>
)
}
return(
<>
<GetChildrens />
</>
)
}
[남은 해결 과제....]
1. 그런데 부모에서 scrollIntoView를 적용하거나, 부모요소에 현재시간 표시 등을 넣는 기능을 사용할 경우,
또 다시 자식 요소는 전체 리렌더링 된다.
( scrollIntoView 코드에 대한 건 미해결,
현재시간 표시 등 부모 컴포넌트에서 무관한 상태 변화 시 자식 요소 리렌더링 되는 문제는 해결 => forwardRef 참고)
'오류' 카테고리의 다른 글
GSAP ScrollTrigger pin 오류 / 해결방안 추가 (2) | 2025.08.09 |
---|---|
ts project에 .js 형식 파일이 있을 경우 > Cannot write file {경로} because it would overwrite input file. (0) | 2025.05.27 |
React 자식 요소의 리렌더링 방지 방법 (0) | 2025.05.21 |
Typescript 환경에서 image를 import 하지 못할 때 (0) | 2025.04.02 |
scss 파일 생성 시 자동으로 .css 파일과 .css.map 파일 생성될 때 (0) | 2025.04.02 |