회원정보는 어느 컴포넌트에서나 자주 쓰이는 데이터이다. 따라서, 상위 컴포넌트에서 최하위 컴포넌트까지 props
로 정보를 넘겨줘야 하는 경우가 많이 생길 수 있다.
따라서, 회원정보는 Context
에 담아두고, 여러 컴포넌트가 바로바로 꺼내다 쓸 수 있게 만들어주자!
createContext
interface State {
authenticated: boolean;
user: User | undefined;
loading: boolean;
}
const StateContext = createContext<State>({
authenticated: false,
user: null,
loading: true,
});
const DispatchContext = createContext<any>(null);
src/types.tsx
export interface User {
username: string;
email: string;
createdAt: string;
updatedAt: string;
}
Provider
export const AuthProvider = ({ children }: { children: React.ReactNode }) => {
return (
<DispatchContext.Provider value={dispatch}>
<StateContext.Provider value={state}>{children}</StateContext.Provider>
</DispatchContext.Provider>
);
};
src/api/_app.tsx
export default function App({ Component, pageProps }: AppProps) {
...
return (
<AuthProvider>
<Component {...pageProps} />;
</AuthProvider>
);
}
StateContext Provider
의 value
와 DispatchContext Provider
의 value
에 넣어줄 값을 구해야 한다.
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);
1️⃣ dispatch
를 export
2️⃣ 백엔드로부터의 response 데이터값 중 user 정보을 dispatch
로 전달하고, LOGIN
이라는 action
을 취하게 한다.
src/pages/login.tsx
const dispatch = useAuthDispatch(); // 1️⃣
...
dispatch('LOGIN', res.data?.user); // 2️⃣
✅ 로그인 전에는 인증이 false, 유저정보가 null인 것을 확인
✅ 로그인 후에는 인증이 true, 유저정보가 존재하는 것을 확인