Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor/#182-B: 회의록 선택시 불필요한 리렌더링 방지 #184

Merged
merged 7 commits into from
Dec 1, 2022

Conversation

dohun31
Copy link
Member

@dohun31 dohun31 commented Dec 1, 2022

🤠 개요

💫 설명

  • 회의록 선택 시 사이드바의 헤더나 MemberList가 리렌더링 되고 있었어요.
  • 이 부분은 회의록 선택할 때 마다 렌더링 될 필요가 없어서 memoization 해줬습니다.

🌜 고민거리 (Optional)

Q. MomList 는 클릭할때마다 계속 리렌더링이 돼요. (해결 - 4번이랑 댓글 확인해주세요.)

devtool로 확인해보면 계속 하이라이팅이 되고 있어요. 아무리 memo하고 별짓 다 해봐도 계속 그래요.

눈물나요. 무지성 memo 하고 있었는데 이 부분 제대로 공부해볼래요...

💇 시도해본거

  1. return값을 useMemo로 감싸기
console.log("mom-list");

return useMemo(() => {
  console.log('re-render!!');
  return (
    <div className={style['mom-list-container']}>
      <h2>회의록</h2>
      <ul className={style['mom-list']}>
        {momList.map(({ _id: id }) => (
          <li key={id} onClick={() => onSelect(id)}>
            {id}
          </li>
        ))}
      </ul>
      <button onClick={onCreateMom}>+ 회의록 추가</button>
    </div>
  );
}, [moms]);
  • 결과
    • 이렇게 하면 워크스페이스가 바뀔 때만 "re-render"가 콘솔에 찍히고, 클릭할 땐 'mom-list"만 찍혀요.
    • 그래도 리렌더링은 계속 일어나고 있어요.
  • 문제점
    • 신기하게도 현재 선택한 워크스페이스의 momList가 다음 워크스페이스를 클릭할 때 반영이돼요.
    1. "왭" 워크스페이스 클릭 -> 이전 워크스페이스의 회의록
    2. "TEST" 워크스페이스 클릭 -> (1)에서 선택한 워크스페이스(왭)의 회의록
    3. "CRDT" 워크스페이스 클릭 -> (2)에서 선택한 워크스페이스(TEST)의 회의록
    
  • 해결 방법
    • 제가 바보였어요. dependency array에 moms가 아니라 momList를 넣어야 했어요.
    • 그래도 여전히 리렌더링은 발생해요.
2022-12-01.8.03.06.mov
  1. 컴포넌트를 memo로 감싸기
export default memo(MomList);
  • 결과
    • 계속 리렌더링이 돼요.
  1. (1) + (2)
  • 결과
    • (1)이랑 똑같이 순서가 뒤죽박죽이에요. 리렌더링이 계속 일어나요.
  1. selectedMom 관련된것들 props로 내려줬어요.
// Sidebar.tsx
function Sidebar({ workspace }: SidebarProps) {
  const { setSelectedMom } = useSelectedMom();

  return (
    <div className={style['sidebar-container']}>
      <Header name={workspace.name} />
      <MemberList members={workspace.members} />
      <MomList moms={workspace.moms} setSelectedMom={setSelectedMom} />
      <ConfButton />
    </div>
  );
}

// MomList.tsx

export default memo(MomList);
  • 결과
    • 원하는 결과를 얻었어요. 리렌더링이 되지 않아요.
    • 아직 Sidebar는 이전과 똑같은 상황에서도 리렌더링이 발생해요.
    • 그런데 그 안의 요소들이 다 memoization 되어 있어서 크게 영향은 없을 것 같아요.
    • 공부해보고 나중에 리팩토링 해볼게요!
2022-12-01.10.13.49.mov

📷 스크린샷 (Optional)

  • 일단 Sidebar의 Header, MemberList, Confbar는 리렌더링이 일어나지 않아요!
2022-12-01.7.49.20.mov
  • 해결
2022-12-01.10.13.49.mov

@dohun31 dohun31 added 🐥 Frontend 프론트엔드 작업 🛠️ Refactor 리팩토링 작업 labels Dec 1, 2022
@dohun31 dohun31 requested a review from a team December 1, 2022 11:08
@dohun31 dohun31 self-assigned this Dec 1, 2022
Copy link
Collaborator

@se030 se030 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍🏻

@se030
Copy link
Collaborator

se030 commented Dec 1, 2022

리렌더링 발생하는 원인은 context인데 자료 찾아보니 selectedMom / setSelectedMom 분리하거나 useMemo 사용하면 되는 것 같아요..?

문제 분석

이 댓글이 정리 잘해놨어요

🙋🏻‍♀️ 근데 시도해본거 1 dep arr에 momList 넣어도 리렌더링 계속 발생하는건가요 ..??

Copy link
Member

@wcho21 wcho21 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

짧은 PR 좋아요

@dohun31
Copy link
Member Author

dohun31 commented Dec 1, 2022

이거 읽어보고 있어요.

context와 렌더링에 관한 post - 자료
re-render와 memoization에 관한 post - 자료

@dohun31
Copy link
Member Author

dohun31 commented Dec 1, 2022

제가 이해한바로는 Context의 값이 변하면 memoization을 하더라도 context를 사용중인 컴포넌트의 리렌더링을 막을 수 없는것 같아요. (뇌피셜이에요)

const { /** selectedMom , */ setSelectedMom } = useSelectedMom();

MomList에서 selectedMom(변하는 값)을 사용하지 않아서 상관이 없을 줄 알았는데 구조분해 할당이랑 상관없이 다음과 같은 흐름으로 리렌더링이 되는것 같아요.
Context 변경 -> useSelectedMom 훅의 context 변경 -> 컴포넌트 리렌더링

그래서 Sidebar에서 useSelectedMom을 호출해서 context 값을 읽고, MomList에 props로 내려주면 MomList의 memoization은 성공적으로 돼요!
하지만 Sidebar는 context를 사용하고 있기 때문에 memoization으로 리렌더링을 막을 수 없어요.

memoization을 위해서 parent에서 props를 내려주고 있는데 이렇게 되면 context를 사용하는 이유가 사라진 느낌이에요 ㅋㅋㅋㅋ... ㅜㅜ

이 부분에 대해서 조금 더 공부해서 확실한 증거를 가져 올게요.

@dohun31 dohun31 merged commit 581f6b5 into dev Dec 1, 2022
@dohun31 dohun31 deleted the refactor/#182-B branch December 1, 2022 15:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🐥 Frontend 프론트엔드 작업 🛠️ Refactor 리팩토링 작업
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Refactor: 회의록 선택 시 불필요한 렌더링이 되는 곳 memoization하기
3 participants