[React hooks] React.memo & useCallback

jr_necki·2022년 8월 17일
0

hooks

목록 보기
3/5
post-thumbnail

✔ 컴포넌트가 리렌더링 되는 경우

  1. 본인이 가진 state 가 변경될 때
  2. 부모 컴포넌트가 리렌더링 될 떄
  3. props가 변경될 때


일기를 수정하는데 네모칸이 리렌더링 될 필요는 없다.

✔ React.memo

React는 먼저 컴퍼넌트를 렌더링(rendering) 한 뒤, 이전 렌더된 결과와 비교하여 DOM 업데이트를 결정한다. 만약 렌더 결과가 이전과 다르다면, React는 DOM을 업데이트한다.

컴퍼넌트가 React.memo()로 래핑 될 때, React는 컴퍼넌트를 렌더링하고 결과를 메모이징(Memoizing)한다. 그리고 다음 렌더링이 일어날 때 props가 같다면, React는 메모이징(Memoizing)된 내용을 재사용한다.

즉,React.memo를 사용하면 일기 수정을 해도 네모 칸 부분인 DiaryEditor.js 의 props는 동일하므로 리렌더링을 방지 할 수 있다.

✔ 사용법

컴포넌트를 감싸서 React.memo를 해주거나

export default React.memo(DiaryEditor);

이렇게 해주면 완료~

✔ 더 확실히...

const DiaryEditor = ({ onCreate }) => {
    useEffect(() => {
        console.log("DiaryEditor 렌더");
    });

App.js에서 보낸 props인 onCreate 함수가 계속 변하기 때문에 DiaryEditor가 리렌더링 되는것이다. 왜냐하면 일기를 삭제하거나 새로 쓰면, 리렌더링이 되고 onCreate함수또한 새로 만들어지므로, 얕은 비교를 하기 때문에 onCreate이라는 props가 다르다고 판별되어 리렌더링 되는것이다.

결론은 onCreate 재생성을 막아서 최적화를 시키자!!!

✔ useCallback

위에서 한대로 useMemo를 이용하고 싶지만,, useMemo는 함수가 아닌 값을 리턴하는 것이므로 불가능하다. 따라서 useCallback을 사용해야한다.

const memoizedCallback = useCallback(
  () => {
    doSomething(a, b);
  },
  [a, b],
);

a,b가 바뀌지 않는다면 첫번째 인자로 받은 콜백함수를 재사용하는 훅이다.

여튼 이거를 onCreate함수에 적용시켜보았다.

  const onCreate = useCallback((author, content, emotion) => {
    const created_date = new Date().getTime();
    const newItem = {
      author,
      content,
      emotion,
      created_date,
      // id가 필요한데 이거는 변수처럼 이용해야함.
      id: dataId.current,
    };
    dataId.current += 1;
   
  },[]);

그러나 이렇게 하면 초기값이 []빈 배열인거로 기억하기 때문에 일기를 추가하면 전에 있던것이 빈배열 + 새로 추가한것 해서 1개만 생성이 된다.
이를 해결하기 위해서는
setData()를 이용해야한다.
저 안에

setData((data)=>[newItem,...data])

이걸 넣어주면 setData로 데이터를 불러와서 해결가능하다!

✔ 결과


일기를 삭제해도 리렌더링 되지 않는다.

profile
슉슉슉

0개의 댓글