본문 바로가기

React

[React] useContext

1. prop drilling의 단점

- 여러 컴포넌트를 통해 공유하고자 하는 데이터를 자식에게 계속 넘겨주어야 함

- 거쳐가는 컴포넌트 중에는 직접적인 사용을 하지 않더라도, 전달하는 역할 때문에 값을 받아야 함

=> 컴포넌트의 재사용이 힘들 수 있음 

2. 해결책 : 

- 컨텍스트 값을 생성하고 해당 값을 제공하여 다수의 컴포넌트 또는 앱의 모든 컴포넌트를 묶어줌 

- prop drilling 없이도 상태값과의 연결이 용이함

 

3. 사용방법

import {createContext, useState, useReducer} from 'react';


// 아래와 같은 기본 값 설정이유 : 자동완성 기능 얻을 수 있음
// 다른 컴포넌트에서 context값 사용시 자동 완성으로 값 추천 해줌
export const ItemContext = createContext({
	items:[],
    addItem: () => {},
    
});


 // 방법 2 useReducer 사용시
// state : 최신 상태값
// action
function itemReducer(state, action){
    
    
	if(action.type === 'ADD'){
    	let updatedItems
  
        	// 로직 작성
            
        return {
            ...state,
            items: updatedItems
    	}
     
    }

	

}

// 컨텍스트 데이터 관리
// 데이터를 앱에 제공
export default function ItemContextProvider({children}){
	
	/*
    방법 1
 	useReducer 없이 사용 시 
	const [itemCart, setItemCart] = useState({
    	items: [],
    });
    
    function handleAddItem(id){
    	setItemCart((prev)=>{
        	const updatedItems = [...prev.itmes,id]
            
            return updatedItens;
        })
    }
    
   const ctxValue ={
    items: itemCart.itmes,
    addItem: handleAddItem
   }
    
    */
    // 방법 2 useReducer 사용시
    //     상태값       액션 					  액션 함수,  초기상태값
	const [itemState, itemDispatch] = useReducer(itemReducer,{
    	items: [],
    });
    
    function handleAddItem(id){
    	itemDispatch({
        	type: 'ADD',
            payload: id // 아무 key 이름 상관 없음
        });
    }
    
   const ctxValue ={
   	items: itemState.itmes,
    addItem: handleAddItem
   }
 
 // children : 어떤 JSX 코드나 다른 컴포넌트
 return <ItemContext.Provider value={ctxValue}>{children}</ItemContext.Provider>

}

ItemContext는 react에 의해 생성됨.

Provider컴포넌트를 갖고 있음. 

 

useReducer : 하나 이상의 복잡한 값을 단순한 형태로 만드는 함수

import ItemContextProvider from './store/item-context.jsx'

function App(){

	return (
    	<ItemContextProvider>
        	<Header />
            <Component/>
            <Component2/>
            <Component3/>
        </ItemContextProvider>
    )

}

=> context를 생성 후 ItemContext.Provider 로 묶어주면 하위 컴포넌트에서 prop drilling없이 데이터를 공유 할 수 있음

 

import {useContext} from 'react';
import {ItemContext} from '../store/item-context.jsx';

export default function Component(){
	const itemCtx = useContext(ItemContext);
    
    return (
    	<>
        	{itemCtx.itmes.length === 0 && <p>아이템 없음</p>}
        </>
    
    )

}

 

 

사용 단점

 

- 앱 내의 여러 컴포넌트 간의 데이터 공유에 유용하나, 컨텍스트를 통해 공유될 값의 설정을 컴포넌트 내에서 함

- 복잡한 앱인 경우 하나의 앱 안에 여러개의 컨텍스트가 있을 가능성도 있기 때문에 다른 상태값을 각각의 다른 컨텍스트로 공유해야할 것이므로 App에 엄청난 로직이 쌓일 가능성이 있음

'React' 카테고리의 다른 글

[React] Http 연결, fetch  (0) 2024.04.16
[React] memo, useMemo  (0) 2024.04.11
[React] useEffect, useCallback  (0) 2024.04.05
[React] Refs, Portals  (0) 2024.04.04
[React] React Developer Tools  (0) 2024.04.03