[REACT] Context API

youngseo·2022년 8월 2일
0

REACT

목록 보기
36/52
post-thumbnail

Context API

리액트에는 내장된 내부 state 저장소가 있습니다.이를 react context라고 합니다.

  • Props가 많은 컴포넌트를 통해 많은 데이터를 전달하는 경우 예기치 못한 문제를 방지할 수 있습니다.

step1

  1. context 파일 만들기
    components > store > auth-context.js
  • AuthContext로 파일명을 만들 수도 있지만 이경우 컴포넌트를 저장한다는 의미가 크기에 케밥케이스로 작성해줍니다.

auath-context.js

import React from 'react'
const AuthContext = React.createContext({
  isLoggedIn: false,
})
  • AuthContext자체가 컴포넌트는 아니지만 컴포넌트를 포함할 객체이기 때문에 카멜케이스로 작성해줍니다.
  1. 컨텍스트를 사용하려면 두가지 작업이 필요합니다.

첫번째: 컴포넌트를 공급

  • 접근 권한부여
  • 공급한다는 것은 JSX코드로 감싼다는 이야기입니다.
    (컨텍스트를 사용하는 컴포넌트의 태그를 JSX로 랩핑)
  • <AuthContext.Provider>로 감싼 하위 컴포넌트 모두 context API사용이 가능합니다.

ex) MainHeader, Login컴포넌트에서 context API가 필요한 경우

import AuthContext from './components/store/auth-context'
return (
  <AuthContext.Provider
    value={{
      isLoggedIn: isLoggedIn,
    }}
  >
    <MainHeader /*isAuthenticated={isLoggedIn}더이상필요하지 않음*/
      onLogout={logoutHandler}
    />
    <main>
      {!isLoggedIn && <Login onLogin={loginHandler} />}
      {isLoggedIn && <Home onLogout={logoutHandler} />}
    </main>
  </AuthContext.Provider>
)
  • AuthContext 그 자체로는 컴포넌트가 아니기에 react의 Provider속성을 이용합니다.
  • value={}라는 프롭을 가져야합니다.

두번째 hook을 연결하고 관찰해야합니다.

  • listening의 경우 custom 또는 react hook을 이용해 할 수 있습니다.

    1. react hook 이용
<AuthContext.Consumer>
  {(ctx) => {
    return (
      <nav className={classes.nav}>
        <ul>
          {props.isLoggedIn && (
            <li>
              <a href="/">Users</a>
            </li>
          )}
          {props.isLoggedIn && (
            <li>
              <a href="/">Admin</a>
            </li>
          )}
          {props.isLoggedIn && (
            <li>
              <button onClick={props.onLogout}>Logout</button>
            </li>
          )}
        </ul>
      </nav>
    )
  }}
</AuthContext.Consumer>
  • <AuthContext.Consumer>태그로 한번 감싸준 후 그 안에서 {(cxt) => { retrun }} 함수를 호출합니다.
  • return 되는 값에 감싼 태그를 넣어줍니다.
  • isLoggedIn의props를 cxt로 변경해줍니다.

step2 useContext훅으로 tapping하기

  • 리액트에 내장된 useContext 훅을 사용하면 다른 컨텍스트를 사용할 수 있습니다.
import React, { useContext } from 'react'
const Navigation = (props) => {
  const ctx = useContext(AuthContext)
  return (
    <nav className={classes.nav}>
      <ul>
        {ctx.isLoggedIn && (
          <li>
            <a href="/">Users</a>
          </li>
        )}
    ...
  )
  • <AuthContext.Consumer>태그로 한번 감싸준 후 그 안에서{(cxt) => { retrun }} 함수를 호출했던 과정을 줄여줍니다.

step3 context API를 동적을 만들기

사용하는 쪽

  <AuthContext.Provider
    value={{
      isLoggedIn: isLoggedIn,
      onLogout: logoutHandler
    }}
  >
  • isLoggedIn외에도 onLogout핸들러함수를 보내줄 수도 있습니다.
  • 문자열이나 객체 등의 값을 전달할 수는 없지만 함수를 전달할 수는 있습니다.

auth-context

const AuthContext = React.createContext({
  isLoggedIn: false,
  onLogout: () => {},
})
  • 위와 같이 빈 함수를 넣어주면 IDE를 조금 더 편하게 사용을 수 있습니다.

stpe4 사용자 정의 컨텍스트 제공자 구성요소 및 빌드 사용

만약, auth-context에 더 많은 로직을 가져와 사용을 하고 싶은 경우에는 어떻게 해야할까요?
즉, 별도의 컨텍스트 관리 컴포넌트를 만들고싶은 경우에는 어떻게 해야할까요?

이런 경우 auth-context파일 내에서 AuthContextProvider라는 하나의 컴포넌트를 만들 수 있습니다.

auth-context

...
export const AuthContextProvider = (props) => {
  return <AuthContext.Provider>{props.children}</AuthContext.Provider>
}
export default AuthContext

위와 같이 props를 받아와 들어온 모든 것을 전달할 수 있습니다. 또한 AuthContext뿐만 아니라 AuthContextProvider도 내보내줍니다.

이렇게 props를 받는 하나의 컴포넌트를 만들어준다면 App.js에서 만든 긴 코드를 App.js에서 분리를 해 사용을 할 수 있습니다. 이렇게 프로젝트를 중앙집중적인 접근방식으로 변경할 수 있습니다.

auth-context

import React, { useState } from 'react'
const AuthContext = React.createContext({
  isLoggedIn: false,
  onLogout: () => {},
  onLogin: (email, password) => {},
})
export const AuthContextProvider = (props) => {
//App.js에서 사용하던 로직을 가져옵니다.
  const { isLoggedIn, setIsLoggedIn } = useState(false)
  const logoutHandler = () => {
    setIsLoggedIn(false)
  }
  const loginHandler = () => {
    setIsLoggedIn(true)
  }
  return (
    <AuthContext.Provider
      value={{
        isLoggedIn: isLoggedIn,
        onLogout: logoutHandler,
        onLogIn: loginHandler,
      }}
    >
      {props.children}
    </AuthContext.Provider>
  )
}
export default AuthContext

0개의 댓글