React 전역 상태 관리 - React Context 편

Saul (사울)·2022년 10월 9일
0

React & React Native

목록 보기
2/2

React Context

  • 리액트에 빌트인 되어 있어 제3의 라이브러리 설치 없이도 사용 가능하다 (== 의존성을 줄일 수 있다)
  • 연습 예시: 회원 로그인

Step 1: 커스텀 훅 만들기

유저 기기에 회원 auth 정보를 저장할 수 있는 기능을 커스텀 훅으로 제작한다. 재사용을 위해 따로 디렉토리를 만들어 저장한다.

// useLocalStorage.ts

import { useState } from 'react';
import AsyncStorage from '@react-native-async-storage/async-storage';

export const useLocalStorage = () => {
  const [value, setValue] = useState<string | null>(null);

  const setItem = (key: string, value: string) => {
    localStorage.setItem(key, value);
    setValue(value);
  };

  const getItem = (key: string) => {
    const value = localStorage.getItem(key);
    setValue(value);
    return value;
  };

  const removeItem = (key: string) => {
    localStorage.removeItem(key);
    setValue(null);
  };

  return { value, setItem, getItem, removeItem };
};

회원 auth 정보를 context와 localStorage에 저장하는 커스텀 훅을 만든다.

// useUser.ts

import { useContext } from 'react';
import { AuthContext } from '../context/AuthContext';
import { useLocalStorage } from './useLocalStorage';

export interface User {
  id: string;
  name: string;
  email: string;
  authToken?: string;
}

export const useUser = () => {
  const { user, setUser } = useContext(AuthContext);
  const { setItem } = useLocalStorage();

  const addUser = (user: User) => {
    setUser(user);
    setItem('user', JSON.stringify(user));
  };

  const removeUser = () => {
    setUser(null);
    setItem('user', '');
  };

  return { user, login, logout };
};

위에 두가지 훅을 사용할 때다. 또 하나의 훅을 만들어 로그인과 로그아웃 함수까지 추가해본다.

// useAuth.ts

import { useEffect } from 'react';
import { useUser } from './useUser';
import { useLocalStorage } from './useLocalStorage';

export const useAuth = () => {
  const { user, addUser, removeUser } = useUser();
  const { getItem } = useLocalStorage();

  useEffect(() => {
    const user = getItem('user');
    if (user) {
      addUser(JSON.parse(user));
    }
  }, []);

  const login = (user: User) => {
    addUser(user);
  };

  const logout = () => {
    removeUser();
  };

  return { user, login, logout };
};

Step 2: React Context

// AuthContext.ts

import { createContext } from 'react';
import { User } from '../hooks/useUser';

interface AuthContext {
  user: User | null;
  setUser: (user: User | null) => void;
}

export const AuthContext = createContext<AuthContext>({
  user: null,
  setUser: () => {},
});

Step 3: App을 context provider로 감싸기

최상단 (주로 App.tsx) 파일에 가서 context provider로 app을 감싼다.

// App.tsx

import { AuthContext } from './context/AuthContext';
import { useAuth } from './hooks/useAuth';

const App = () => {
  const { user, login, logout } = useAuth();

  return (
    <AuthContext.Provider value={{ user, setUser }}>
      <div className="App">
        <h1>Hello CodeSandbox</h1>
        <h2>Start editing to see some magic happen!</h2>
      </div>
    </AuthContext.Provider>
  );
};

export default App;

Step 4: 로그인 페이지 만들기

import { useAuth } from '../hooks/useAuth';

const Login = () => {
  const { login } = useAuth();

  const handleLogin = () => {
    login({
      id: '1',
      name: 'John Doe',
      email: 'john.doe@email.com',
    });
  };

  return (
    <div>
      <h1>Login</h1>
      <button onClick={handleLogin}>Login</button>
    </div>
  );
};

export default Login;

Step 5: 로그아웃 버튼 만들기

import { useAuth } from '../hooks/useAuth';

const LogoutButton = () => {
  const { logout } = useAuth();

  return <button onClick={logout}>Logout</button>;
};

export default LogoutButton;
profile
모바일 & 블록체인

0개의 댓글