15. Context API

hey hey·2021년 12월 17일
0

리액트 배우기

목록 보기
23/26
post-thumbnail
  • 로그인 정보
  • 애플리케이션 환경 설정
  • 테마 등 전역적으로 사용할 데이터가 있을 때 유용한 기술

새 프로젝트 생성

$ yarn create react-app context-tutorial

1. Context 생성하기

contexts/color.js

import { createContext } from "react";
const ColorContext = createContext({color:'black'})
export default ColorContext

createContext: 새 Context를 만들 때 사용, 기본 상태를 지정한다.

2. Consumer 사용하기

props로 받아오는 것이 아닌 Consumer라는 컴포넌트를 통해 조회를 하겠다.

components/ColorBox.js

import ColorContext from "../contexts/color";

const ColorBox=()=>{
  return(
    <ColorContext.Consumer>
      {value=>(
        <div
          style={{
            width:'64px',
            height:'64px',
            background:value.color
          }}
        />
      )}
    </ColorContext.Consumer>
  )
}
export default ColorBox

Consumer 사이에 중괄호를 열어서 그 안에 함수를 넣어준다.

이런 패턴을 Function as a child 혹은 Render Props 라고 부른다.

컴포넌트의 children이 있어야 할 자리에 일반 JSX 혹은 문자열이 아닌 함수를 전달한다.

3. Provider 사용하기

Context의 value를 변경할 수 있다.

Provider를 사용할 때는 value 값을 명시해 줘야 한다

import ColorBox from './components/ColorBox';
import ColorContext from './contexts/color';

function App() {
  return (
    <ColorContext.Provider value={{color:'red'}}>
      <>
        <ColorBox></ColorBox>
      </>
    </ColorContext.Provider>
  );
}

export default App;

동적 Context 사용하기

context의 value에는 무조건 상태값만 있어야 하는 것이 아니다 → 함수도 가능

contexts/color.js

import { createContext ,useState } from "react";
const ColorContext = createContext({
  state:{color:'black',subcolor:'red'},
  actions:{
    setColor : ()=>{},
    setSubcolor:()=>{}
  }
});
const ColorProvider = ({children})=>{
  const [color,setColor] = useState('black')
  const [subcolor,setSubcolor] = useState('red')
  const value ={
    state:{color,subcolor},
    actions:{setColor,setSubcolor}
  };
  return (
    <ColorContext.Provider value={value}>{children}</ColorContext.Provider>
  )
}
const {Consumer:ColorConsumer} = ColorContext
export {ColorProvider,ColorConsumer}
export default ColorContext

ColorProvider라는 컴포넌트를 새로 작성했다.

그리고 그 컴포넌트에서는 ColorContext.Provider를 렌더링하고 있다.

이 Provider의 value에는 상태는 state로 업데이트 함수는 actions으로 묶어서 전달하고 있다.

CreateContext를 사용할 때 기본값으로 Provider의 value에 넣는 객체의 형태와 일치시키는게 좋다.

ColorBox.js

import {ColorConsumer} from "../contexts/color";

const ColorBox=()=>{
  return(
    <ColorConsumer>
      {value=>(
        <><div
          style={{
            width:'300px',
            height:'300px',
            background:value.state.color
          }}
        />
        <div 
          style={{
            width:'32px',
            height:'32px',
            background:value.state.subcolor
}}
        />
        </>
      )}
    </ColorConsumer>
  )
}
export default ColorBox

색상 선택 컴포넌트 만들기

SelectColors.js

import { ColorConsumer } from "../contexts/color"

const colors =['red','orange','yellow','blue','indigo','violet']
const SelectColors = ()=>{
  return (
    <div>
      <h2>색을 입력하세요</h2>
      <ColorConsumer>
      {({actions})=>(
      <div style={{display:'flex'}}>
        {colors.map(color=>(
          <div
            key={color}
            style={{
              background:color,
              width:'24px',
              height:'24px',
              cursor:'pointer'
            }}
            onClick={()=>actions.setColor(color)}
            onContextMenu={e=>{ // 우클릭 
              e.preventDefault() // 우클릭시 메뉴 뜨기 막기
              actions.setSubcolor(color)
            }}
          />
        ))}
      </div>)}
      </ColorConsumer>
    </div>
  )
}
export default SelectColors

App.js

import ColorBox from './components/ColorBox';
import ColorContext, { ColorProvider } from './contexts/color';
import SelectColors from './components/SelectColors';
function App() {
  return (
    <ColorProvider>
      <>
        <SelectColors></SelectColors>
        <ColorBox></ColorBox>
      </>
    </ColorProvider>
  );
}

export default App;

useContext Hook 사용하기

ColorBox.js

import ColorContext from "../contexts/color";
import React,{useContext} from 'react'

const ColorBox=()=>{
  const {state} = useContext(ColorContext)
  return(
    <div>
      {value=>(
        <><div
          style={{
            width:'300px',
            height:'300px',
            background:state.color
          }}
        />
        <div 
          style={{
            width:'32px',
            height:'32px',
            background:state.subcolor
        }}
        />
        </>
      )}
    </div>
  )
}
export default ColorBox

너무 어려워요.......

Redux로 넘어가면 나을수도...?

profile
FE - devp

0개의 댓글