리마인드 ContextAPI
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