인프런 영문 브랜드 로고
인프런 영문 브랜드 로고

인프런 커뮤니티 질문&답변

빙봉님의 프로필 이미지
빙봉

작성한 질문수

한 입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지

12.16) Diary 페이지 구현하기

최적화하기 11분 50초

해결된 질문

작성

·

393

0

import React from "react";
import { useNavigate } from "react-router-dom";
import MyButton from "./MyButton";

const DiaryItem = ({ id, emotion, content, date }) => {
  const navigate = useNavigate();
  const goDetail = () => {
    navigate(`/diary/${id}`);
  };
  const goEdit = () => {
    navigate(`/edit/${id}`);
  };
  const strDate = new Date(parseInt(date)).toLocaleDateString();
  return (
    <div className="DiaryItem">
      <div
        onClick={goDetail}
        className={[
          "emotion_img_wrapper",
          `emotion_img_wrapper_${emotion}`,
        ].join(" ")}
      >
        <img src={process.env.PUBLIC_URL + `assets/emotion${emotion}.png`} />
      </div>
      <div className="info_wrapper" onClick={goDetail}>
        <div className="diary_date">{strDate}</div>
        <div className="diary_content_preview">{content.slice(0, 25)}</div>
      </div>
      <div className="btn_wrapper">
        <MyButton text={"수정하기"} onClick={goEdit} />
      </div>
    </div>
  );
};
export default React.memo(DiaryItem); // 왜 렌더링 계속 되지?ㅡㅡㅡㅡㅡ

안녕하세요 강사님!

최적화 하는 과정에서 DiaryItem 에 React.memo를 적용시켰는데도 렌더링이 계속됩니다ㅜ

혹시 useNavigate 부분 코드때문에 그럴까요?

구글링해보니까
'원인은 react-router가 V6로 업그레이드 되면서 URL이 변경 될 경우 useNavigate함수를 계속 재생성하도록 변경 되었다는것을 알게 되었습니다.'
이런 글을 읽어서요,, 답변부탁드립니다!

강의 잘 듣고 있습니다. 좋은 강의 감사합니다!

답변 2

1

이정환 Winterlood님의 프로필 이미지
이정환 Winterlood
지식공유자

안녕하세요 이정환입니다.

우선 감정 일기장까지 다 만드셨군요 이제 완강이 얼마 남지 않았네요 축하드립니다 🎉🎉

 

원인 확인해 보았습니다.

생각보다 간단한 이유였는데요

보내주신 코드에 보면 DiaryList 컴포넌트에서 DiaryItem을 렌더링 할 때에

children Props를 내려보내주고 있는 걸 확인할 수 있습니다.

( {it.content} {it.emotion} 부분이 children Props 입니다 )

image

사실 이 Props는 DiaryItem 컴포넌트가 완성된 이후로는 불필요하죠?

아마 테스트 단계에서 만들어 두셨다가 깜빡하고 지우지 않으신 걸로 보입니다.

 

문제는 children Props는 DiaryList가 리렌더 될 때 마다 다시 생성됩니다.

(getProcessedDiaryList 함수의 반환값이 달라지기 때문인데요)

그렇기 때문에 DiaryItem에 React.memo를 적용해 메모이제이션된 컴포넌트로 만들어도

리렌더가 발생하게 되는 것 입니다.

 

문제의 원인을 해결하시려면 이 children Props 를 제거해 주시면 됩니다.

image

추가적으로 보통의 불필요한 리렌더는

리렌더가 일어나는 컴포넌트보다는 해당 컴포넌트의 부모 컴포넌트에 문제가 있을 가능성이 큽니다.

그러니 앞으로의 리액트 프로그래밍에서도 부모 컴포넌트에서

뭔가 문제가 있는지 먼저 확인하시는 습관을 들이시면

오류를 찾고 해결하시기에 더욱 수월하실거라고 생각됩니다

감사합니다 😃

빙봉님의 프로필 이미지
빙봉
질문자

헉 너무 감사합니다!!!!

1

이정환 Winterlood님의 프로필 이미지
이정환 Winterlood
지식공유자

안녕하세요 이정환입니다.

정확한 원인을 파악하기 위해 현재 프로젝트의 코드를

코드샌드박스 혹은 깃허브에 업로드 하신 다음

링크를 올려주시면 확인해보겠습니다 😃

빙봉님의 프로필 이미지
빙봉

작성한 질문수

질문하기