Context API을 사용해 컴포넌트 데이터 공유하기

soll·2022년 8월 31일

FootballProject

목록 보기
4/6
post-thumbnail

프로젝트를 진행 하면서 컴포넌트들 간에 데이터를 공유해야 할 상황이 발생했다. Context API에 대해서 설명하는 글이나 공식문서도 이미 여럿 존재하기 때문에 본 글에서는 Context API을 사용하게된 계기와 간단한 사용법을 남기려고 한다.

Context API란?

context를 이용하면 단계마다 일일이 props를 넘겨주지 않고도 컴포넌트 트리 전체에 데이터를 제공할 수 있습니다.
React 공식문서

프로젝트 구조

Context API을 적용한 프로젝트의 일부 구조는 아래 사진과 같이 구성되어있다.

MatchSelector 컴포넌트는 부모 컴포넌트로 Context API의 Provider을 통해 자식 컴포넌트들을 감싸고 있다. DatePcikerFilterMatch 컴포넌트에서 사용자들에게 보여줄 경기 정보를 날짜와 그외 다른 요소들로 필터링 하여 MatchList 컴포넌트에 List형태로 보여줄 계획이다.

여러 컴포넌트들간 데이터 공유

결국 자식 컴포넌트들 끼리는 정보가 공유되어야 한다. 이번 프로젝트를 예로 들면 MatchList 컴포넌트에서는 서버에 필터링 정보를 서버에게 보내는 정보를 가지고 있어야 하며 DatePickerFilterMatch 컴포넌트에서 그 정보들을 계속 업데이트하여 MatchList 컴포넌트에게 알려 주어야 한다.

만약 Context API 혹은 Redux 같은 state management 라이브러리를 사용하지 않을 경우 부모 컴포넌트에 state와 setstate함수를 선언하여 자식 컴포넌트들에게 매번 props로 넘겨 주어야 한다. 이미 내 프로젝트에는 사용자가 로그인시 로그인 정보를 저장하기 위해 Redux을 세팅해 둔 상태였지만 이번 state공유는 오직 MatchSelector 컴포넌트만을 위한 데이터 이기 때문이라고 생각하여 Context API로 처리하기로 했다.

Context API을 사용하기전 고려할점

  1. 다양한 레벨에 네스팅된 많은 컴포넌트에게 데이터를 전달해야 할 때.
    즉, 여러 레벨에 걸쳐 최하위 자식에게 데이터를 전달해야 할 상황에서는(props drilling현상) React 공식문서에서는 컴포넌트 합성을 권유한다고 되어있다.(React 공식문서)

  2. 컴포넌트 재사용이 필요할 경우는 Context API사용을 피하자.
    이 부분은 개발에 들어가기 전까지는 잘 이해가 되지 않았다. 개인적인 생각으로는, DatePicker 컴포넌트를 예로 들면, 해당 컴포넌트의 순수 기능은 사용자가 날짜를 선택하여 Provider에게 알려주는 기능이다. 이 컴포넌트를 경기 날짜 필터링 용도가 아닌 다른 용도의 날짜 필터링 기능으로 사용하기 위해서는 꽤 번거로운 작업을 해야할 것 같다. (useContext훅 내의 context 을 매개변수로 받는 등의 작업)

Context API 사용하기

Provider 만들기

Provider.tsx

export interface MatchKeys {
  time?: string;
  gender?: string;
  deadline?: boolean;
  num?: number;
  address?: string;
}

interface MatchInfoProps {
  matchData: MatchKeys;
  setMatchData: Dispatch<SetStateAction<{}>>;
}
export const Context = createContext<[MatchInfoProps]>({
  matchData: {},
  setMatchData: () => {},
});

export const Provider = ({
  children,
}: {
  children: React.ReactNode;
}) => {
  const [matchInfo, setMatchInfo] = useState({});
  return (
    <MatchInfoContext.Provider
      value={{
        matchData: matchInfo,
        setMatchData: setMatchInfo,
      }}
    >
      {children}
    </MatchInfoContext.Provider>
  );
};

Provider에는 createContext을 통해 Context을 생성하고 Provider을 통해 공유해야 할 state값들을 value내에 명시해 주었다. matchData을 통해 정보를 조회하고 setMatchData을 통해 정보를 수정한다.

useContext훅을 통해 데이터 접근 및 수정하기

const DatePicker = () => {
  const { matchData, setMatchData } = useContext(MatchInfoContext);
  const onDateChange: DatePickerProps['onChange'] = (date, dateString) => {
    setMatchData({
      ...matchData,
      time: dateString,
    });
  };
  return (
  	...
  );
};

export default DatePicker;

자식 컴포넌트들 중 하나인 DatePicker 코드이다. useContext훅을 통해 context을 담아 Provider에서 지정한 value값들을 가져와 수정한 코드이다.

마지막으로, 다른 자식들 컴포넌트에서 마찬가지로 useContext을 통해 matchData을 조회하면 매번 수정되어 state값들을 공유하는 것을 볼 수 있다.

참고

https://ko.reactjs.org/docs/context.html

profile
프론트 엔드 개발자입니다.

0개의 댓글