리액트에서 props를 부모-자식(위-아래)이 아닌 여러 컴포넌트에 전달해야 할 때 context를 사용하면 props로 넘겨주지 않아도 정보를 공유할 수 있다!
상황에 따라 Context를 사용하는 게 나은지, 컴포넌트로 넘겨주는게 나은지 판단을 잘 해야 효율적으로 사용할 수 있다(꼭 필요할 때만 사용하자!).
JavaScript
//context.js
import React, { createContext } from "react";
export const MyContext = React.createContext(defaultValue);
TypeScript
////context.ts
import React, { createContext } from "react";
//type 예시
export type ContextType = "light" | "dark";
//interface 예시(배열, 함수)
interface ContextType {
myArr: [],
myFunc: (): void => {},
}
export const MyContext = createContext<ContextType>("light");
import { createContext } from "react";
interface UserContextType {
username: string;
}
const UserContext = createContext<UserContextType | null>(null);
createContext()
JavaScript
//App.js
import { useState } from "react";
import { MyContext } from './context';
const Add = () => {
const [theme, setTheme] = useState("light");
return(
//MyContext에 해당하는 context를 provide
<MyContext.Provider value={theme}>
<MyComponent />
</MyContext.Provider>
);
}
TypeScript
//App.ts
import { useState } from "react";
import { ContextType,MyContext } from './context';
const Add = () => {
const [theme, setTheme] = useState<ContextType>("light");
return(
<MyContext.Provider value={theme}>
<MyComponent />
</MyContext.Provider>
);
}
return(
<MyContext.Consumer>
{value => 로직~}
</MyContext.Consumer>
)
import { useContext } from "react";
import { MyContext } from "./context";
const MyTheme = () => {
const theme = useContext(MyContext);
return <p>현재 테마 : {theme}</p>
}
Context 흐름
const [state, dispatch] = useReducer(reducer함수, 기본값);
(state, action) => newState
의 형태로 reducer를 받는다.dispatch({type: 'action명'})
//카운터 만들기 예시
//초기값 설정
const initialState = {count: 0};
//reducer함수(반드시 이름이 reducer일 필요는 없다. 하지만 보통은 reducer라고 짓는 것 같다.)
function reducer(state, action) {
switch (action.type) {
//action.type이 increment라면 state.count에 1을 증가시킴
case 'increment':
return {count: state.count + 1};
//action.type이 decrement state.count에 1을 감소시킴
case 'decrement':
return {count: state.count - 1};
default:
throw new Error();
}
}
//useReducer 사용해서 상태값 관리
function Counter() {
const [state, dispatch] = useReducer(reducer, initialState);
return (
<>
Count: {state.count}
<button onClick={() => dispatch({type: 'decrement'})}>-</button>
<button onClick={() => dispatch({type: 'increment'})}>+</button>
</>
);
이론만 봐서는 어떻게 사용하는건지는 알겠는데.. 언제 어디서 써야 하는지 감이 오지 않는다.
간단한 예시를 통해서 연습을 먼저 해보고 필요하다면 프로젝트에 활용해봐야겠다.
출처
Context - React
Context | React TypeScript cheatsheet
Hooks API Reference(usecontext) - React
벨로퍼트와 함께하는 모던 리액트 - Context API를 사용한 전역 값 관리
Hooks API Reference - React
벨로퍼트와 함께하는 모던 리액트 - useReducer 를 사용하여 상태 업데이트 로직 분리하기