리액트 useContext

Rock Kyun·2023년 11월 8일
3
post-custom-banner

오늘의 학습

  • 전역 상태관리, createContext(), useContext()

useContext

  • 리액트의 컴포넌트 중
    공통적으로 쓰이는 state를 계속 하위 컴포넌트에
    props로 전달하면 props drilling이 발생하는데
    이 문제를 해결하는 것이 Context이다.

사용법_context 준비

  • JSX 파일 생성.

  • 컴포넌트 기본 골격 생성.

  • createContext() 를 담은 변수를 생성. (export를 붙여주자)

  • 컴포넌트의 props에 children 을 전달.

  • 외부로 전달하고 싶은 state를 생성.

  • 위에 생성한 <context 변수명.Provider> 로 감싼 {children props}를 return 한다.

return <createContext()를 담은 변수.Provider>
  {children}
</createContext()를 담은 변수.Provider>
  • context.Providervalue 속성으로 전달하고자 하는 state를 넣는다.
<createContext()를 담은 변수.Provider value = {{state}}>
  {children}
</createContext()를 담은 변수.Provider>

Context 준비 예시

<context.jsx>

import React, { createContext, useEffect, useState } from "react";

// context 생성
export const JSONData = createContext(); 

// children props 전달
export default function JsonPlaceHolder({ children }) { 
  // 공유하고자 하는 state 생성
  const [jsonData, setJsonData] = useState([]); 

  async function getJson() {
    let res = await fetch(`https://jsonplaceholder.typicode.com/todos/1`);
    let data = await res.json();
    setJsonData((prev) => [...prev, data]);
  }

  useEffect(() => {
    getJson();
  }, []);

  // 반환 값
  return <JSONData.Provider value={{ jsonData }}>{children}</JSONData.Provider>;
}

사용법_context 사용

  • state를 전달하고자 하는 컴포넌트를 context 컴포넌트로 감싼다.
<App.jsx>

import './App.css';
import ContextTest from './components/Context';
import JsonPlaceHolder from './context/JsonPlaceHolder';

function App() {

  return (
    <div className="App">
      <JsonPlaceHolder>
        <ContextTest />
      </JsonPlaceHolder>
    </div>
  );
}

export default App;
  • context를 사용하고자 하는 컴포넌트로 이동 (감싸진 children 컴포넌트로 이동)
  • 변수를 생성하는데 useContext()를 사용한다. (구조분해 할당 가능)
    useContext()의 인자는 createContext()를 할당했던 변수 이다.

Context 사용 예시

<ContextTest.jsx>

import React, { useContext } from "react";
// createContext() 변수 import
import { JSONData } from "../context/JsonPlaceHolder";

export default function ContextTest() {
  // context.Provider의 value로 전달한 값을 가져온다.
  // 구조분해 할당을 사용하지 않으면 객체 형태로 온다
  // ex) const data = useContext(JSONData); // {jsonData: Array(2)}
  const { jsonData } = useContext(JSONData); // (2) [{…}, {…}]
  
  
  
  return (
    <div>
      <h3>-context API-</h3>
      <h4>
        이것은 contextAPI를 활용해 가져온 데이터 입니다:
        {jsonData?.map((el, i) => {
          return (
            <div key={i}>
              <h4>오늘의 할 일 {i+1}</h4>
              <p>{el.title}</p>
              <h4>완료 상태</h4>
              <p>{el.completed}</p>
            </div>
          );
        })}
      </h4>
    </div>
  );
}

Context 주의사항

  • context 생성한 컴포넌트에서
    공유 중인 state의 값을 변경하면
    공유 받은 컴포넌트에서도 전부 재렌더가 일어난다.
    이는 매우 비효율적이며 성능에 아주 안 좋다.
    따라서 이 단점을 보완할 수 있는
    메모이제이션(React.memo, useCallback, useMemo)을 사용하자!

느낀 점

  • 아직 Redux를 하나도 모르지만
    Context와 같은 기능을 하는 거 같은데...
    리액트에 내장되어 있는 Context를 안 쓰고
    왜 Redux를 사용하는지 잘 모르겠다.
    Redux는 준비 부분도 복잡한 거 같던데..😅
    Redux를 배워보면 알겠쥐
post-custom-banner

0개의 댓글