강의

멘토링

로드맵

Inflearn brand logo image

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

남기정님의 프로필 이미지
남기정

작성한 질문수

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

11.3) Context 분리하기

usecallback과 usememo를 중복해서 쓰는 이유(context 분리하기 챕터)

해결된 질문

작성

·

24

·

수정됨

0

안녕하세요 강의를 잘 듣고있습니다.

하지만 개념이 잘 이해가 되지 않은 부분들이 있어서 질문드립니다.

context 분리하기 강의 부분입니다!!!

  1. 이부분에서 이미 전 시간에 만들었던 useCallback으로 선언했던 함수들이 있습니다. 하지만 왜 app컴포넌트의 렌더링으로 인해 또 함수 선언이 되어 usememo를 써야한다고 하셨는지 문의드려요.

      const onCreate = useCallback((content) => {
        dispatch({
          type: "CREATE",
          data: {
            id: idRef.current++,
            isDone: false,
            content: content,
            date: new Date().getTime(),
          },
        });
      }, []);
    
      const onUpdate = useCallback((targetId) => {
        dispatch({
          type: "UPDATE",
          targetId: targetId,
        });
      }, []);
    
      const onDelete = useCallback((targetId) => {
        dispatch({
          type: "DELETE",
          targetId: targetId,
        });
      }, []);
const memoizedDispatch = useMemo(() => {
    return { onCreate, onUpdate, onDelete };
  }, []);
  1. 그동안 다른 컴포넌트에 props를 줄때는 color={color}식으로 주고, 이는 객체형태라고 합니다. 받는 자식 컴포넌트에서는 {color} 이런식으로 구조분해할당을 합니다.

     

    하지만 createContext로 만든 provider value ={} 는 기본적으로 객체형태가 아닌걸까요? 기본적으로 구조분해할당을 하지 않는거같아서 뭐지싶었습니다

    <TodoDispatchContext.Provider value={memoizedDispatch}>
  2. useEffect, useMemo의 차이점은 무엇인가요? 기본적으로 의존성 배열을 []로 둘때는 처음으로 컴포넌트가 mount 될때만 실행하고 , [todos]를 넣으면 이 변수 state가 바뀔때만 실행하는거같아서 똑같은거같아요

     

답변 2

0

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

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

3번 -> 2번 -> 1번 요 순서대로 답변드릴게요!

 

3) useEffect vs useMemo

두 Hooks 모두 의존성 배열에 담긴 값이 변화했을때 콜백함수를 실행시키는 것은 동일하나, useMemo는 콜백함수의 값을 반환하는 반면 useEffect는 결과를 반환하지 않습니다.

이런 차이점으로 인해 useEffect는 보통 특정 시점에 값을 반환할 필요 없는 동작을 정의할때 사용되고, useMemo는 특정 시점에 계산해야 할(계산해 반환해야 할 값)을 정의할 때 사용합니다.

이에 대한 설명은 우리 강의의 10.2 챕터를 다시 참고하시면 좋을듯 합니다.

 

2) Provider 컴포넌트에게 value Props를 전달할 때

Provider 컴포넌트에게 value Props로 전달되는 값 역시 Props이므로 객체 형태로 전달됩니다.

다만 Context의 Provider 컴포넌트는 우리가 직접 구현하는게 아닌, React에서 자체적으로 제공하는 내장 컴포넌트이므로 전달한 Props에 대한 구조 분해 할당을 직접 구현하실 필요는 없습니다.

Context의 Provider는 그저 Props로 전달받은 객체를 그대로 하위 컴포넌트들에게 공급하는 역할만 딱 깔끔하게 수행합니다.

 

1) useMemo를 사용해야 하는 이유

이유는 간단합니다. 그렇지 않으면 함수들을 감싸고 있는 객체가 리렌더링 되기 때문입니다.

우선 onCreate, onUpdate, onDelete 함수들 자체는 각각 useCallback으로 감싸져서 컴포넌트가 리렌더링 되어도 다시 생성되지 않습니다.

그러나 이 세 함수를 감싼{ onCreate, onUpdate, onDelete } 객체 자체는 컴포넌트 리렌더링시 다시 생성됩니다. 그리고 우리가 Provider 컴포넌트에게 Props로 전달해야 하는 값은 이 객체입니다.

따라서 { onCreate, onUpdate, onDelete } 객체가 다시 생성되지 않도록 useMemo를 활용해야합니다.

남기정님의 프로필 이미지
남기정
질문자

감사합니다!!!

0

안녕하세요, 인프런 AI 인턴입니다. 남기정님.

Context 분리하기에서 useCallbackuseMemo의 사용은 주로 최적화와 관련이 있습니다. 이에 대한 설명을 드리겠습니다.

1. useCallbackuseMemo의 중복 사용 이유

  • useCallback: 특정 함수가 불필요하게 재생성되는 것을 방지하기 위해 사용합니다. 컴포넌트의 의존성이 변하지 않는 한 같은 인스턴스의 함수를 반환합니다.
  • useMemo: 값이나 객체를 캐싱하여 불필요하게 다시 계산되는 것을 방지합니다. 여기서는 onCreate, onUpdate, onDelete를 포함하는 객체를 메모이제이션하여 Provider에 전달될 값이 재생성되지 않도록 합니다.

이러한 최적화를 통해 컴포넌트의 리렌더링을 방지하고 성능을 개선할 수 있습니다. 함수 자체는 useCallback으로 최적화했지만, 이 함수들을 모아서 하나의 객체로 만드니, 해당 객체는 useMemo로 최적화한 것입니다.

2. createContext로 만든 Provider의 value

Context의 Provider에 전달하는 value는 객체 형태로 저장됩니다. 하지만 자식 컴포넌트에서는 Context를 통해 값을 접근하므로, 명시적으로 구조분해할당을 하지 않아도 됩니다. 이는 Context API의 특성에 따라 제공되어 값이 항상 동일하게 전달되기 때문입니다.

3. useEffectuseMemo의 차이점

  • useEffect: 사이드 이펙트를 다루고 컴포넌트의 생명주기를 효과적으로 활용하기 위해 사용됩니다. API 호출, 이벤트 리스너 등록 등의 일을 처리할 수 있습니다.
  • useMemo: 연산 비용이 큰 계산을 캐싱하기 위해 사용됩니다. 컴포넌트가 리렌더링될 때 재계산하는 것을 방지하여 성능을 최적화합니다.

쉽게 말해, useEffect는 주로 부수효과를 처리하는 데 사용하고, useMemo는 값의 캐싱이나 계산 결과의 메모이제이션에 사용됩니다.

관련 질문이 도움이 될 것입니다:

  1. Context 분리하기 중에서 memoizedDispatch에 useMemo를 사용하는 이유가 궁금합니다.
    여기서는 useMemouseCallback의 사용 이유에 대해 상세하게 설명하고 유사한 질문에 대한 답변이 제공되었습니다.

  2. context, 최적화 관련 질문
    이 질문에서는 DispatchContext의 최적화와 관련하여 ‘useMemo’를 사용할 경우를 설명합니다.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

남기정님의 프로필 이미지
남기정

작성한 질문수

질문하기