- context 예제
- useReducer
1) context 예제 1
import { createContext, useState } from "react";
export const ChangeColorContext = createContext()
const ChangeColorProvider = (props) => {
const [color, setCoolr] = useState('tomato')
const onColor = (color) => {
setCoolr(color)
}
return (
<ChangeColorContext.Provider value={{ color, onColor }}>
{props.children}
</ChangeColorContext.Provider>
);
};
export default ChangeColorProvider;
ChangeColorProvider 안에 들어올 컴포넌트에서 사용할 props를 관리할 관리자를 만들어 준다.
위 코드에선 color와 onColor를 넘겨주었다.
const ChangeColor = () => {
const { color, onColor } = useContext(ChangeColorContext)
return (
<div>
<h2 style={{ color: color }}>색상 UI : {color}</h2>
<p>
<button onClick={()=>onColor('red')}>Red</button>
<button onClick={()=>onColor('green')}>Green</button>
<button onClick={()=>onColor('blue')}>Blue</button>
<button onClick={()=>onColor('black')}>Black</button>
</p>
</div>
);
};
그리고 props를 사용할 컴포넌트에서 useContext를 사용해 불러온다.
const { color, onColor } = useContext(ChangeColorContext)
const App = () => {
return (
<div>
<ChangeColorProvider>
<ChangeColor />
</ChangeColorProvider>
마지막으로 App.js에서 Provider로 컴포넌트를 감싸주면 사용이 가능하다.


const ChangeColorProvider = (props) => {
const [color, setCoolr] = useState('tomato')
color의 초기값을 tomato로 설정했기 때문에 처음 출력되는 내용과 style의 색은 tomato가 된다.
2) context 예제 2
같은 방법으로 숫자를 증감시키는 예제를 만들었다.
import { createContext, useState } from "react";
export const CntContext = createContext()
const CntProvider = (props) => {
const [cnt, setCnt] = useState(1)
const increment = step => {
step ? setCnt(cnt+step) : setCnt(cnt+1)
}
const decrement = step => {
step ? setCnt(cnt-step) : setCnt(cnt-1)
}
return (
<CntContext.Provider value={{ cnt, increment, decrement }}>
{props.children}
</CntContext.Provider>
);
};
export default CntProvider;
위 코드에서 increment, decrement 함수를 호출할 때 매개변수를 넘기지 않으면 +/- 1씩 되게 삼항연산자를 사용했는데, 아래와 같이 작성 가능하다.
step의 값이 넘어오지 않으면 step의 초기값을 1로 설정하도록 했다.
const increment = (step = 1) => {
setCnt(cnt + step)
}
const decrement = (step = 1) => {
setCnt(cnt - step)
}
const Cnt = () => {
const { cnt, increment, decrement } = useContext(CntContext)
return (
<div>
<h2>숫자 UI : {cnt}</h2>
<p>
<button onClick={()=>decrement(100)}>-100</button>
<button onClick={()=>decrement(10)}>-10</button>
<button onClick={()=>decrement()}>-1 (전달값X)</button>
<button onClick={()=>increment()}>+1 (전달값X)</button>
<button onClick={()=>increment(10)}>+10</button>
<button onClick={()=>increment(100)}>+100</button>
</p>
</div>
);
};
3) useReducer
React 컴포넌트에서 상태 관리를 할 때 그동안 useState 훅을 사용했다.
useSatae는 한 가지 상태, 간단한 상태 관리를 할 때 사용하면 유리하고, useReducer의 경우 좀 더 복잡한 상태 관리를 할때 사용한다.
useReducer는 state와 action을 받아 state를 업데이트해준다.
import { createContext, useReducer } from "react";
export const CounterContext = createContext()
const initialState = {count : 0}
const reducer = (state, action) => {
switch (action.type) {
case 'INCREMENT':
return {
count: state.count + 1
}
case 'DECREMENT':
return {
count: state.count - 1
}
case 'RESET':
return {
count: 0
}
default:
return state
}
}
const CounterProvider = (props) => {
const [state, dispatch] = useReducer(reducer, initialState)
const { count } = state
return (
<CounterContext.Provider value={{count, dispatch}}>
{props.children}
</CounterContext.Provider>
);
};
export default CounterProvider;
initialState로 count의 초기값을 설정해 주고 reducer 함수를 만들어 state와 action을 매개변수로 받는다.
INCREMENT인 경우 +1을 해주고 DECREMENT인 경우 -1, RESET이면 count를 0으로 초기화해 준다.
그 후 하위 컴포넌트에 count와 dispatch를 넘겨준다.
(dispatch는 reducer 함수에 action을 전달하는 함수이다.)
import React, { useContext } from 'react';
import { CounterContext } from '../../contexts/CounterContext';
const Counter = () => {
const { count, dispatch } = useContext(CounterContext)
return (
<div>
<h2>reducer UI : {count}</h2>
<p>
<button onClick={() => dispatch({ type: 'INCREMENT' })}>Increment</button>
<button onClick={() => dispatch({ type: 'DECREMENT' })}>Decrement</button>
<button onClick={() => dispatch({ type: 'RESET' })}> Reset</button >
</p >
</div >
);
};
export default Counter;
