useContext()
react 공식문서 Context 살펴보기
Context는 리액트 컴포넌트 트리에서 글로벌하다고 판단되는 데이터(현재 인증받은 유저나 테마, 선호 언어 등)를 공유하기 위해 설계되었다. 변동이 적은 데이터에 쓰인다.
React.createContext
에서 반환값으로 <컴포넌트.Provider>
로 최상위 컴포넌트를 감싼다.export
하여 <컴포넌트.Consumer>
로 컨텍스트 사용할 곳에 위치// -------------------------
// 최상위 스토어역할의 컴포넌트
// -------------------------
export const MyContext = React.createContext(); // export 해주기!
<MyContext.Provider value={{여기에 state들 나열..}}>
<ComponentA/>
<ComponentB/>
<ComponentC/>
</MyContext.Provider>
// -------------------------
// 하위 컴포넌트에서 사용하기
// -------------------------
import React, { useContext } from 'react';
import { MyContext } from './Root';
// 사용법 1 : 태그 감싸기 ---------------------------
return (
<MyContext.Consumeer>
여기서 사용할거야
</MyContext.Consumeer>
)
// 사용법 2 : useContext(컨텍스트) 사용하기 -----------
const ctx1 = useContext(MyContext1);
const {...value} = useContext(MyContext); // 최상위 스토어 불러와서 모든 스테이트를 불러온다.
return (
<div>
{ctx1}
{age} // value.age
</div>
)
추가
<Context.Consumer>
대신 useReducer
를 통해 하위 컴포넌트를 감싸지 않고 사용하기
// 스토어 설정
export const initStateUser = { name: 'hwang' } // useReducer에 인자로 넘김
export const reducer = (state, action)=>{ // useReducer에 인자로 넘김
const {type, payload} = action
switch(type){
case 'SET_USER' :
return { ...state, name: payload }
case 'RESET':
return { ...initStateUser }
}
}
export const setUser = (payload)=> ({ type: 'SET_USER', payload })
export const reset = () => ({type: 'RESET' })
const UserContext = createContext(initStateUser)
export default UserContext
// 전역 프로바이더 컴포넌트 -> 최상위 컴포넌트를 감싸줄 [전역-프로바이더-컴포넌트]
import UserContext from './UserContext'
import TodoContext from './TodoContext' // 기타등등 모든 프로바이더 불러와~
const GlobalProvider = ({children}) => {
return (
<UserContext.UserProvider value={초기값을 설정안했다면 여기에서}>
<TodoContext.TodoProvider>
<ETC...Provider>
{children} // 하위 컴포넌트를 Provider 들로 감싸 전역 프로바이더 만들기
</ETC...Provider>
</TodoContext.TodoProvider>
</UserContext.UserProvider>
)
}
// 최상위 컴포넌트 + 전역 프로바이더 컴포넌트
import GlobalProvider from '.../GlobalProvider'
const App = ()=> {
return (
<GlobalProvider>
<div>최상위 컴포넌트</div> // children 이 되지요
</GlobalProvider>
)
}
// 사용 컴포넌트
import {useReducer} from 'react'
import {reducer, initStateUser, setUser } from '/UserContext'
// setUser 는 액션함수, 리듀서에 액션을 전달(type, payload)
const UserInfoCompo = ()=> {
const [user, dispatch] = useReducer(reducer, initStateUser)
return (
<> // props로 store를 전달 받지 않아도 되며, Consumer 컴포넌트를 감쌀 필요없음
<p>{user.name}</p> // 'hwang'
<button onClick={()=> dispatch(setUser('eungee'))}>
// dispatch({type:'SET_USER',payload: 'eungee'})
// 버튼 클릭시 -> user.name 은 'eungee' 로 변경
</>
)
}