프론트엔드/React

리마인드 ContextAPI

반신욕좋아하는J 2023. 2. 9. 20:37
반응형

1. Context API 란?

전역적으로 사용해야되는 데이터를 관리하는 기능

context API 는 context 에서 무언가 변경이 일어날때 context 를 사용하는 컴포넌트가 어떤것이있는지 관련이있는지를 알아내서 바꾸는게 아닌 useContext 를 사용하는 모든 컴포넌트가 재 랜더링되게된다.

그렇기 때문에 최적화 측면에서 많은 반복이 있는 state 들을 관리하기 적합하지않다.

그런경우는 보통 전역적인 state 를 관리하고 최적화까지 이뤄지는 redux 를 사용하는것이 낫다.

그래서 주로 인증상태나 테마 같은 경우 사용된다. ( 고반복적인 관리가 필요없는것들 )

2. 사용방법

root/index.js

import React from "react";
import ReactDOM from "react-dom";
import { BrowserRouter } from "react-router-dom";

import "./index.css";
import App from "./App";
import ProductsProvider from "./components/context/products-context";

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
  **<ProductsProvider>**
    <BrowserRouter>
      <App />
    </BrowserRouter>
  **</ProductsProvider>**
);

context/products-context.js


import React, { useState } from "react";

// 1. createContext 를 통해서 context 객체를 생성한다.
// createContext 내부 매개변수는 provider 를 찾지못했을경우 쓰이는 기본값이다.
export const ProductsContext = React.createContext({
  products: [],
  toggleFav: (id) => {},
});

// 2. Provider 
const ProductsProvider = (props) => {
  const [productsList, setProductsList] = useState([
    {
      id: "p1",
      title: "Red Scarf",
      description: "A pretty red scarf.",
      isFavorite: false,
    },
    {
      id: "p2",
      title: "Blue T-Shirt",
      description: "A pretty blue t-shirt.",
      isFavorite: false,
    },
    {
      id: "p3",
      title: "Green Trousers",
      description: "A pair of lightly green trousers.",
      isFavorite: false,
    },
    {
      id: "p4",
      title: "Orange Hat",
      description: "Street style! An orange hat.",
      isFavorite: false,
    },
  ]);

  const toggleFavorite = (productId) => {
    setProductsList((crrenProdList) => {
      const prodIndex = crrenProdList.findIndex((p) => p.id === productId);
      const newFavStatus = !crrenProdList[prodIndex].isFavorite;
      const updatedProducts = [...crrenProdList];
      updatedProducts[prodIndex] = {
        ...crrenProdList[prodIndex],
        isFavorite: newFavStatus,
      };
      return updatedProducts;
    });
  };
  return (
    <ProductsContext.Provider
      value={{ products: productsList, toggleFav: toggleFavorite }}
    >
      {props.children}
    </ProductsContext.Provider>
  );
};

export default ProductsProvider;

components/Products.js


import React, { useContext } from "react";

import { ProductsContext } from "../components/context/products-context";

import ProductItem from "../components/Products/ProductItem";
import "./Products.css";

const Products = (props) => {
  **const productList = useContext(ProductsContext).products;**
  return (
    <ul className="products-list">
      {productList.map((prod) => (
        <ProductItem
          key={prod.id}
          id={prod.id}
          title={prod.title}
          description={prod.description}
          isFav={prod.isFavorite}
        />
      ))}
    </ul>
  );
};

export default Products;

간단히 상품데이터를 좋아요 누른기준으로 렌더링하는 페이지에서 상품state를 contextAPI 를 통해서 관리해보자.

1. createContext 를 통해서 context 객체를 생성한다.

context 객체를 사용하고있는 컴포넌트를 렌더링할때 react 트리 에서 가장 가까이 있는 Provider 에서 값을 읽어온다.

근데 Provider 가 없다면 ? 그럴경우 createContext 내부 매개변수 안에 있는 데이터들을 기본 값으로 사용한다.

2. productsList 를 useState 로 생성하고 기본값으로 데이터들을 하드코딩해준다.

3.< ProductsContext.Provider>

.Provider 를 사용해서 context 를 사용하는 컴포넌트들에게 context 가 변화하면 알리는 역활이다.

이 컴포넌트의 props 로 value 를 지정할수있다. 이것은 하위에있는 컴포넌트들에게 전달된다.

여기서 value 의 props 들이 바뀔때마다 사용되고있는 컴폰너트들은 모두 재 렌더링되게된다.

4. 작성했던 context API 를 index.js 에 적용한다.

root 디렉토리안에 index.js 에서 contextAPI 를 사용할수있도록 ProductsProvider 로 감싸준다.

5. useContext () 로 사용

사용하고자 하는 컴폰너트에 접근해서 useContext() 훅을 사용해서 context 를 꺼내 이용할수있다.

 

https://ko.reactjs.org/docs/context.html#consuming-multiple-contexts

 

Context – React

A JavaScript library for building user interfaces

ko.reactjs.org

반응형