StudyForYou / ouahhan-typescript-with-react

우아한 타입스크립트 with 리액트 스터디 레포 🧵
4 stars 0 forks source link

#29 [10장_1] 시간이 지나도 변하지 않는 상태(ex. 스토어 객체)를 관리하는 방법은 무엇인가요? #47

Open drizzle96 opened 2 months ago

drizzle96 commented 2 months ago

❓문제

시간이 지나도 변하지 않는 상태(ex. 스토어 객체)를 관리하는 방법은 무엇인가요?

🎯답변

hyeyoonS commented 1 month ago

시간이 지나도 변하지 않는 상태는 useMemo로 관리할 수 있습니당. useMemo를 사용하여 컴포넌트가 마운트될 때만 객체 인스턴스를 생성하고 이후 렌더링에서는 이전 인스턴스를 재활용할 수 있도록 구현할 수 있습니다.

//예시 코드
import React from 'react';

const Component: React.VFC = () => {
const store = useMemo(() => new Store(), []);
return (
    <StoreProvider store={store}>
        <Children>
    </StoreProvider>
   )  ;
};
qooktree1 commented 1 month ago

useRef로 관리할 수 있다고 생각합니다. 동일한 값을 참조할 때는 변화하는 값인 상태를 관리하는 state가 아닌 ref가 적합하다고 생각했습니다.

drizzle96 commented 1 month ago

렌더링 시마다 객체 참조 동일성을 유지하는 방법은 2가지가 있습니다.

if(!store.current) store.current = new Store();



두 방법은 기능적으로 동일합니다. 하지만 useState를 사용하는건 의미론적으로 좋은 방법이 아닙니다. useState는 본래 시간이 지나면서 변화되어 렌더링에 영향을 주는 '상태'를 정의하기 위한 훅으로 만들어 진 것이기 때문입니다. 

따라서 useRef가 동일한 객체 참조를 유지하는 목적으로 사용하기에 가장 적합한 훅입니다.

이 때 유의할 점은 useRef의 인자에 null이 아닌 new Store()를 사용하면 안됩니다. new Store()를 사용하면 렌더링 시마다 ref 참조가 변하는건 아니지만 new Store()가 실행되어 불필요한 인스턴스가 생성됩니다.

cf. (책의 내용에 따르면) useMemo는 객체 참조 동일성을 유지하기 위한 목적으로 권장되는 방법이 아니라고 합니다. 리액트 공식 문서에 따르면 useMemo를 통한 메모이제이션은 의미상 보장된 것이 아니고 오로지 성능 향상을 위한 용도로만 사용돼야 한다고 언급하고 있습니다. 예를 들어 리액트에서는 메모리 확보를 위해 이전 메모이제이션 데이터가 삭제될 수 있다고 합니다.