PJH's Community Site - Context

박정호·2022년 11월 22일
0

Community Project

목록 보기
5/14
post-thumbnail

🚀 Start

회원정보는 어느 컴포넌트에서나 자주 쓰이는 데이터이다. 따라서, 상위 컴포넌트에서 최하위 컴포넌트까지 props로 정보를 넘겨줘야 하는 경우가 많이 생길 수 있다.

따라서, 회원정보는 Context에 담아두고, 여러 컴포넌트가 바로바로 꺼내다 쓸 수 있게 만들어주자!



✏️ Context 폴더 및 auth 파일 생성



✏️ auth 파일 작성

✔️ createContext 생성

createContext

  • Context 객체를 만든다.(Context는 리액트 프로젝트에서 전역으로 사용되는 데이터를 이용할 때 사용되는 기능)
  • Context 객체를 구독하고 있는 컴포넌트를 렌더링할 때 React는 트리 상위에서 가장 가까이 있는 짝이 맞는 Provider로부터 현재값을 읽는다.
interface State {
  authenticated: boolean;
  user: User | undefined;
  loading: boolean;
}

const StateContext = createContext<State>({
  authenticated: false,
  user: null,
  loading: true,
});

const DispatchContext = createContext<any>(null);

✔️ User interface import

  • User정보가 많이 쓰이는만큼 타입을 정의하는 User interface도 자주 사용됨으로 types파일에 별도 생성
src/types.tsx

export interface User {
  username: string;
  email: string;
  createdAt: string;
  updatedAt: string;
}

✔️ Context 사용을 위한 Provider 생성

Provider

  • Provider는 context를 구독하는 컴포넌트들에게 context의 변화를 알리는 역할
  • Provider컴포넌트는 value prop을 받아서 이 값을 하위에 있는 컴포넌트들에게 전달
export const AuthProvider = ({ children }: { children: React.ReactNode }) => {

  return (
    <DispatchContext.Provider value={dispatch}>
      <StateContext.Provider value={state}>{children}</StateContext.Provider>
    </DispatchContext.Provider>
  );
};

✔️ 최상위인 Myapp에서 AuthProvider로 컴포넌트 감싸기

  • 감싸진 하위 컴포넌트들은 이제 context를 사용 가능
src/api/_app.tsx
export default function App({ Component, pageProps }: AppProps) {
		...

  return (
    <AuthProvider>
      <Component {...pageProps} />;
    </AuthProvider>
  );
}

✔️ value 값 정하기

StateContext ProvidervalueDispatchContext Providervalue 에 넣어줄 값을 구해야 한다.

  • StateContext Provider value에 들어갈 값은 유저 정보와 유저 인증 유무 이다.

  • DispatchContext Provider value에 들어갈 값은 유저의 정보를 업데이트하거나 인증 유무를 업데이트하는 것 을 구현하는 것이다.

이 값들은 reducer를 통해 관리하고 업데이트되는 state들이 될 것이다.

dispatch를 통해 action을 전달할 수 있으며, action은 업데이트해야할 정보를 가지고 있다.

예를 들어, login, logout 등의 각자 다른 상황에서 보내지는 state값들은 다를 것이며, 상황에 따라 업데이트 될 것이다.

reducer 생성

interface Action {
  type: string;
  payload: any;
}

const reducer = (state: State, { type, payload }: Action) => {
  switch (type) {
    case 'LOGIN':
      return {
        ...state,
        authenticated: true,
        user: payload,
      };
    case 'LOGOUT':
      return {
        ...state,
        authenticated: false,
        user: null,
      };
    case 'STOP_LOADING':
      return {
        ...state,
        loading: false,
      };
    default:
      throw new Error(`Unknown action type: ${type}`);
  }
};

state 생성 & dispatch 생성

export const AuthProvider = ({ children }: { children: React.ReactNode }) => {
  const [state, defaultDispatch] = useReducer(reducer, {
    user: null,
    authenticated: false,
    loading: true,
  });

  const dispatch = (type: string, payload?: any) => {
    defaultDispatch({ type, payload });
  };

  return ...
};

다른 컴포넌트에서 쉽게 StateContext value와 DispatchContext value를 사용할 수 있게 export 해주기

export const useAuthState = () => useContext(StateContext);
export const useAuthDispatch = () => useContext(DispatchContext);


✏️ Login 성공 후 유저 정보 업데이트

1️⃣ dispatch를 export

2️⃣ 백엔드로부터의 response 데이터값 중 user 정보을 dispatch로 전달하고, LOGIN이라는 action을 취하게 한다.

src/pages/login.tsx

  const dispatch = useAuthDispatch(); // 1️⃣
  ...
  dispatch('LOGIN', res.data?.user); // 2️⃣


✏️ Login 후 업데이트 확인

로그인 전에는 인증이 false, 유저정보가 null인 것을 확인

로그인 후에는 인증이 true, 유저정보가 존재하는 것을 확인

profile
기록하여 기억하고, 계획하여 실천하자. will be a FE developer (HOME버튼을 클릭하여 Notion으로 놀러오세요!)

0개의 댓글

관련 채용 정보