카테고리 없음

useContext

코딩 화이팅 2023. 9. 3. 14:08
  • 전역 상태 관리 : 애플리케이션의 여러 컴포넌트에서 접근해야 하는 상태 값이 있을 때(예: 사용자 정보, 테마 설정 등)
  • 프롭스 터널링 방지 : 중첩된 여러 컴포넌트를 통해 동일한 데이터를 전달해야 하는 경우, Context를 사용하면 중간 컴포넌트들에게 데이터를 전달하지 않고도 깊게 중첩된 자식 컴포넌트에 데이터를 제공할 수 있다.
  • 기능 설정 : 예를 들어, 애플리케이션의 전체 테마 또는 로케일 설정과 같은 기능적인 설정을 컴포넌트 트리 전체에 공유할 때
  • 코드 재사용과 조직 : Context를 사용하면 관련된 데이터와 메서드를 함께 그룹화하여 코드의 재사용성과 조직성을 향상시킬 수 있다.

테마 설정할 ts

theme.ts
export const theme = {
  primary: {
    main: "#3f51b5",
    text: "#fff",
  },
  secondary: {
    main: "#f50057",
    text: "#fff",
  },
};

createContext를 통해 ThemeContext를 만들어줌.

ThemeContext.tsx
import { createContext } from "react";
import { theme } from "./theme";

type ThemeContextProviderProps = {
  children: React.ReactNode;
  자식 컴포넌트를 두기 위해 설정
};

export const ThemeContext = createContext(theme);

export const ThemeContextProvider = ({
  children,
}: ThemeContextProviderProps) => {
  return (
    <ThemeContext.Provider value={theme}>{children}</ThemeContext.Provider>
  );
};

만든 Context를 useContext를 통해 사용해줌.

Box.tsx
import { useContext } from "react";
import { ThemeContext } from "./ThemeContext";

export const Box = () => {
  const theme = useContext(ThemeContext);
  return (
    <div style={{ background: theme.primary.main, color: theme.primary.text }}>
      제목 부분
    </div>
  );
};
App.tsx
import "./App.css";
import { ThemeContextProvider } from "./components/context/ThemeContext";
import { Box } from "./components/context/Box";

function App() {
  return (
    <div className="App">
      <ThemeContextProvider>
        <Box />
      </ThemeContextProvider>
    </div>
  );
}

export default App;

로그인 예제

UserContext.tsx
// React 라이브러리에서 useState와 createContext를 가져옵니다.
import { useState, createContext } from "react";

// 사용자 인증 정보에 대한 타입을 정의합니다.
export type AuthUser = {
  name: string;
  email: string;
};

// UserContext의 타입을 정의합니다.
// 이 타입에는 현재 사용자 정보(user)와 그 정보를 업데이트하는 setUser 함수가 포함됩니다.
type UserContextType = {
  user: AuthUser | null;
  setUser: React.Dispatch<React.SetStateAction<AuthUser | null>>;
};

// UserContextProvider 컴포넌트의 props 타입을 정의합니다.
// 여기에는 children이라는 prop이 포함됩니다.
type UserContextProviderProps = {
  children: React.ReactNode;
};

// UserContext를 생성합니다. 초기값으로 빈 객체를 제공하며, 이 객체는 UserContextType으로 타입 단언됩니다.
export const UserContext = createContext({} as UserContextType);

// UserContext의 값을 제공하는 UserContextProvider 컴포넌트를 정의합니다.
export const UserContextProvider = ({ children }: UserContextProviderProps) => {
  // user 상태를 생성하고 초기값으로 null을 설정합니다.
  const [user, setUser] = useState<AuthUser | null>(null);

  // UserContext.Provider 컴포넌트를 반환하며, 그 내부에는 children이 포함됩니다.
  // value prop을 통해 user 상태와 setUser 함수를 제공합니다.
  return (
    <UserContext.Provider value={{ user, setUser }}>
      {children}
    </UserContext.Provider>
  );
};
User.tsx
// React 라이브러리에서 useContext hook을 가져옵니다.
import { useContext } from "react";
// UserContext를 가져옵니다.
import { UserContext } from "./UserContext";

export const User = () => {
  // UserContext의 값을 userContext 변수에 저장합니다.
  const userContext = useContext(UserContext);

  // 로그인 버튼을 클릭하면 실행될 핸들러 함수입니다.
  // setUser 함수를 호출하여 사용자 정보를 업데이트합니다.
  const handleLogin = () => {
    userContext.setUser({
      name: "강현",
      email: "hyunleo@naver.com",
    });
  };

  // 로그아웃 버튼을 클릭하면 실행될 핸들러 함수입니다.
  // setUser 함수를 호출하여 사용자 정보를 null로 설정하여 로그아웃 상태를 나타냅니다.
  const handleLogout = () => {
    userContext.setUser(null);
  };

  // 사용자의 로그인 상태를 표시하는 UI를 반환합니다.
  return (
    <div>
      <button onClick={handleLogin}>Login</button>
      <button onClick={handleLogout}>Logout</button>
      <div>사용자 이름은 {userContext.user?.name}</div>
      <div>사용자 이메일은 {userContext.user?.email}</div>
    </div>
  );
};
App.tsx
import "./App.css";
import { UserContextProvider } from "./components/context/UserContext";
import { User } from "./components/context/User";

function App() {
  return (
    <div className="App">
      <UserContextProvider>
        <User />
      </UserContextProvider>
    </div>
  );
}

export default App;

로그인을 눌렀을 때

로그아웃을 눌렀을 때