React 11. useContext

윤태현·2023년 7월 10일
0

REACT

목록 보기
12/19
post-thumbnail

useContext

  • Context API를 사용할 수 있도록 해주는 Hook
  • Context API
    • 트리 구조에서 전역적으로 데이터를 공유할 수 있게 도와주는 기능
    • 앱의 전반적인 설정, 로그인한 정보, 테마 등 전체 컴포넌트에서 공유되는 정보를 다룰 때 사용
  • Prop는 맨 밑에 하위 컴포넌트에 전달을 할 경우 중간 컴포넌트는 사용하지 않더라도 전달해야 하는 불편함이 있다.

Prop / useContext

Prop

  • 컴포넌트 계층 구조에서 상위 컴포넌트로부터 하위 컴포넌트로 데이터를 전달하는 표준 방법
  • 일반적으로 부모와 자식 컴포넌트 사이의 직접적인 데이터 전달에 가장 적합
  • prop drilling이라는 문제를 초래할 수 있음
    • 데이터를 여러 계층의 컴포넌트를 통해 전달해야 할 때 발생하는 문제로,
      코드가 복잡해지고 유지 관리가 어려워질 수 있습니다.

useContext

  • 컴포넌트 트리의 모든 레벨에서 props를 통해 수동으로 전달하지 않고도 데이터에 접근할 수 있음
  • 애플리케이션의 전반적인 상태를 관리하거나, 많은 수의 컴포넌트가 동일한 데이터를 필요로 할 때 유용
  • context는 오버헤드가 있으므로 모든 상황에서 사용하는 것이 좋은 방법은 아니다.

사용법

// ToggleContext.jsx	
// Context 객체 생성

import { createContext } from "react";

export const ToggleContext = createContext(null);
// App.js
// Provider를 사용하여 모든 자식 컴포넌트에 값을 공유

import { useState } from 'react';
import Test from "./components/Test";
import { UserContext } from "./context/UserContext";

function App() {
  const [isToggle, setIsToggle] = useState(false);
  
  return (
    <ToggleContext.Provider value={{isToggle, setIsToggle}}>
      <Test />
    </ToggleContext>
  )
}

export default App;
// Test.jsx

import React, { useContext } from 'react';
import { ToggleContext } from '../context/ToggleContext';

const Test = () => {
    const { isToggle, setIsToggle } = useContext(ToggleContext);

    return (
        <div>
            {isToggle ? 'O' : 'X'}
        	<button onClick={() => setIsToggle(!isToggle)}>클릭</button>
        </div>
    );
};

export default Test;

Provider value를 사용하지 않는 경우

// UserContext.jsx
export const UserContext = createContext('홍길동');


// App.js
function App() {
  return (
    <Test />
  )
}


// Test.jsx
const name = useContext(UserContext);
  • Provider에 value 값을 사용하지 않고 createContext에서 defaultValue를 설정할 수 있지만
    동적인 상태 관리와 공유에서는 value를 통해 하위 컴포넌트에게 전달하는 방식이 좋다

여러 개의 Provider를 중첩해서 사용하는 경우

// App.js
function App() {
  return (
    <ThemeContext.Provider value={'light'}>
      <UserContext.Provider value={'홍길동'}>
        <Test />
      </UserContext.Provider>
    </ThemeContext.Provider>
  )
}
  • Provider를 중첩해서 사용할 경우 코드 복잡성, 렌더링 효율성, 재사용성 등이 좋지 않아
    Provider를 하나로 합치는 것이 효율적이다. (다만 이는 최적화 방법이지 항상 필요한 것은 아니다.)
// CombinedProvider.jsx
function CombinedProvider({ providers, children }) {
    return providers.reduce((prev, curr) => React.cloneElement(curr, { children: prev }), children);
}


// App.js
function App() {
  return (
    <CombinedProvider
      providers={[
        <ThemeContext.Provider value={'light'} />,
        <UserContext.Provider value={'홍길동'} />
      ]}
    >
      <Test />
    </CombinedProvider>
  )
}

0개의 댓글