IT이야기

기능이 소품으로 전달될 때 Array.map의 반응 기능 구성 요소가 항상 리렌더링됨

cyworld 2022. 3. 29. 21:49
반응형

기능이 소품으로 전달될 때 Array.map의 반응 기능 구성 요소가 항상 리렌더링됨

모든 자식 상태를 중앙에서 관리하는 부모 구성요소에 여러 개의 버튼을 렌더링하려고 한다.이것은 부모가 클릭 상태, 즉 자신의 상태에 있는 각 버튼에 대해 사용 불가능한 상태를 저장한다는 것을 의미한다.useState아이들에게 소품으로 물려주는 거야또한,onClick함수는 또한 부모 구성요소의 내부에서 정의되며 각 자식에게 전달된다.지금 나는 다음과 같이 하고 있다.

const [isSelected, setIsSelected] = useState(Array(49).fill(false));
...
const onClick = useCallback((index) => {
     const newIsSelected = [...prev];
     newIsSelected[i] = !newIsSelected[i];
     return newIsSelected;
}, []);
...

(In the render function:)

return isSelected.map((isFieldSelected, key) => {
     <React.Fragment key={key}>
          <TheChildComponent
               isSelected={isFieldSelected}
               onClick={onClick}
          />
     </React.Fragment/>
})

사용 중인 어린이 구성 요소의 렌더링을 방지하기 위해...

  • ...useCallbackonClick 기능이 항상 동일하게 유지되는지 확인
  • ...React.Fragment그렇지 않으면 아이가 고유한 ID 또는 유사한 것을 갖지 못하기 때문에 구성 요소를 다시 찾도록 한다.

하위 구성 요소는 다음과 같이 내보내십시오.

export default React.memo(TheChildComponent, compareEquality)와 함께

 const compareEquality = (prev, next) => {
      console.log(prev, next);
      return prev.isSelected === next.isSelected;
 }

어떻게든 로그 라인이 들어와compareEquality결코 실행되지 않는다. 그러므로 나는 안다.compareEquality실행되지 않는다.나도 왜 이런 일이 일어나는지 모르겠어.

나는 모든 블로그, 이전의 Stackoverflow 질문 등을 확인했지만, 적어도 하나의 구성요소가 실행될 때마다 아동 구성요소가 재생되는 것을 막을 수 있는 방법을 아직 찾지 못했다.onClick기능 및 업데이트됨으로써isSelected

만약 누군가가 나를 올바른 방향으로 인도하거나 내 문제가 어디에서 오는지를 설명해 준다면 나는 매우 행복할 것이다.

미리 고마워!

이 코드가 실제로 새 코드를 생성함onClick에 의해 모든 렌더링 기능을 발휘한다.useCallback디프 배열이 제공되지 않음:

const onClick = useCallback((index) => {
     const newIsSelected = [...prev];
     newIsSelected[i] = !newIsSelected[i];
     return newIsSelected;
});

다음 항목만 생성되어야 함onClick모든 렌더에 걸쳐 기능을 수행하고 재사용하십시오.

const onClick = useCallback((index) => {
     const newIsSelected = [...prev];
     newIsSelected[i] = !newIsSelected[i];
     return newIsSelected;
}, []);

바닐라와 결합React.memo이 경우, 이 경우 다음과 같은 경우를 제외하고 아이들이 재교육을 받는 것을 방지해야 한다.isSelected변화들(여러분의 두 번째 주장.React.memo이 또한 수정했어야 했다 - 왜 그것이 작동하지 않았는지 잘 모르겠다.)

참고로 다음 코드를 단순화할 수 있다.

     <React.Fragment key={key}>
          <TheChildComponent
               isSelected={isFieldSelected}
               onClick={onClick}
          />
     </React.Fragment/>

다음과 같은 경우:

          <TheChildComponent key={key}
               isSelected={isFieldSelected}
               onClick={onClick}
          />

(실제로 귀하에게 필요한 구성요소는 본체 내 단일 구성요소뿐임)map).

알고 보니 문제는 둘 다 아니었다.useCallback,useMemo뭐 비슷한 거라도 말이야.

상위 구성요소의 렌더 함수에서 직접 사용하지 않음

return isSelected.map(...)

나는 그 부분을 다음과 같은 분리된 아주 간단한 구성 요소에 포함시켰다.

const Fields = () => {

     return isSelected.map((isFieldSelected, i) => (
       <TheChildComponent
            key={i}
            isSelected={isFieldSelected}
            onClick={onClick}
       />
     ));

};

그게 내 문제가 있던 곳이야.분리형 구성 요소에서 코드를 이동할 때Fields상위 구성 요소의 반환 문구에 리렌더링 오류가 사라졌다.

그래도 도와줘서 고마워.

참조URL: https://stackoverflow.com/questions/68671725/react-functional-components-in-array-map-are-always-rerendering-when-getting-pas

반응형