1. 조상이 자손에게 props를 넘겨주거나
- 자손이 조상에게 이벤트를 넘겨주거나
- 그 외에 연관 없는 컴포넌트들끼리 데이터를 주고 받으려면??
⇒ Redux, Recoil, Mobx, Context API 등을 사용할 수 있음
Context API
- context Provider를 이용해 데이터를 저장/조작하고, Context Consumer로 데이터를 얻어온다.
- Provider가 업데이트 되면, consumer를 쓰는 컴포넌트들이 리렌더링 된다. ⇒ 성능 이슈가 생길 수 있으므로 무분별한 사용은 자제
진행 과정
createContext()
로 컨텍스트 생성
import { createContext } from "react" const TaskContext = createContext()
- consumer 생성
⇒
useContext(컨텍스트)
를 호출하는 함수를 내보낸다⇒ 외부에서 이 훅으로 3에서 만든 상태와 함수들을 얻어올 수 있음
export const useTasks = () => useContext(TaskContext)
컨텍스트를 쓰는 곳마다 useContext를 호출할 수 있지만, 여기서는 커스텀 훅으로 만들어 내보내는 방법을 사용
- provider 함수 생성
- 상태 생성
- 상태를 조작하는 함수를 생성
- 1과 2를 value 값으로 가지는
<컨텍스트.Provider>
컴포넌트를 리턴
⇒ 해당 함수에서 보내고 싶은 상태와 그 상태를 조작하는 함수를 생성
const [tasks, setTasks] = useState([]);
상태 대신 로컬스토리지 값을 얻어올 수도 있다(로컬스토리지 커스텀 훅 참고)
const [tasks, setTasks] = useLocalStorage('tasks',[]);
⇒ 추가, 업데이트, 삭제
import {v4} from 'uuid' .. const addTask = (content) => { setTasks([ ...tasks, { id: v4(), content, completed: false } ]) }
const updateTask = (id, completed) => { setTasks(tasks.map(task=> task.id === id ? {...task, completed}: task) ) }
const deleteTask = (id) => { setTasks(tasks.filter(task=>task.id != id)) }
const TaskProvider = ({children}) => { const [tasks, setTasks] = useState([]); const addTask const updateTask const removeTask return ( <TaskContext.Provider value={{tasks, addTask, updateTask,removeTask}}> {children} </TaskContext.Provider> ) }
- 상태를 공유하고 싶은 컴포넌트에서 (호출 부에서) Provider 컴포넌트로 감싸줌
function App() { return ( <TaskProvider> <Container> <TaskList /> </Container> </TaskProvider> ) }
- 각 컴포넌트에서 consumer 생성 훅으로 상태 등을 얻어옴
export default function TaskList() { const {tasks} = useTasks() return ( {tasks.map(task => ( <Task key={item.id} id={item.id} content={item.content} complete={item.complete} /> )) ) }
- 아이디 생성 라이브러리 ⇒ uuid
- v4()로 랜덤 아이디 생성
import {v4} from 'uuid' { ... id: v4(), .. }