React Hooks #4 useContext()

eunji hwang·2020년 7월 12일
0

REACT

목록 보기
5/16

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>
)
  • useContext를 사용한 곳에서 Provider 컴포넌트를 사용할수 있다.
  • props value를 통해 전달할 state를 정한다
  • 하위 ComponentA,B,C 들은 <MyContext.Consumer>를 최상위 태그로 감사 state를 사용 할 수 있다.

추가

useReducer

<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' 로 변경
    </>
  )
}
profile
TIL 기록 블로그 :: 문제가 있는 글엔 댓글 부탁드려요!

0개의 댓글