'리액트를 다루는 기술' 15장, Context API

devgosunman·2020년 8월 25일
0
post-thumbnail

😎 Context API를 사용한 전역 상태 관리 흐름 이해하기

  • 전역적으로 사용할 데이터를 쉽게 관리해주는 기능이다.
  • 사용자 로그인 정보, 애플리케이션 환경 설정, 테마 등을 관리할 때 쓴다.
  • 리덕스, 리액트 라우터, 스타일드 컴포넌트 등의 라이브러리도 이 기술을 기반으로 구현됐다.
  • 과거에는 리덕스나 Mobx와 같은 상태 관리 라이브러리를 사용하였다.

😋 Context API 사용법 익히기

createContext

  • 새 컨텍스트를 만들 때 쓰는 함수

Provider

  • Provider를 사용하면 Context의 value를 변경할 수 있다.
  • Provider를 사용할 떄는 value 값을 명시해 주어야 제대로 작동한다.
// color.js
import { createContext } from "react";

const ColorContext = createContext({ color: "black" });

export default ColorContext;

// ColorBox.js
import React from "react";
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;

// App.js
import React from "react";
import "./styles.css";
import ColorBox from "./components/ColorBox";
import ColorContext from "./contexts/color";

export default function App() {
  return (
    <ColorContext.Provider value={{ color: "red" }}>
      <div className="App">
        <ColorBox />
      </div>
    </ColorContext.Provider>
  );
}

😁 동적 Context 사용하기

  • Context의 Value에는 상태 값이 아닌 함수도 전달할 수 있다.
// color.js
import React, { 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;


// App.js
import React from "react";
import "./styles.css";
import ColorBox from "./components/ColorBox";
import { ColorProvider } from "./contexts/color";
import SelectColors from "./components/SelectColor";

export default function App() {
  return (
    <ColorProvider>
      <div className="App">
        <SelectColors />
        <ColorBox />
      </div>
    </ColorProvider>
  );
}

// ColorBox.js
import React from "react";
import { ColorConsumer } from "../contexts/color";

const ColorBox = () => {
  return (
    <ColorConsumer>
      {({ state }) => (
        <>
          <div
            style={{
              width: "64px",
              height: "64px",
              background: state.color
            }}
          />
          <div
            style={{
              width: "32px",
              height: "32px",
              background: state.subcolor
            }}
          />
        </>
      )}
    </ColorConsumer>
  );
};

export default ColorBox;


//SelectColor.js
import React from "react";
import { ColorConsumer } from "../contexts/color";

const colors = ["red", "orange", "yellow", "green", "blue", "purple", "violet"];

const SelectColors = () => {
  return (
    <div>
      <h2>Choose the color</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>
            ))}
          </div>
        )}
      </ColorConsumer>
      <hr />
    </div>
  );
};

export default SelectColors;

🙄 Consumer 대신 Hook 또는 static contextType 사용하기

useContext Hook

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

const ColorBox = () => {
  const { state } = useContext(ColorContext);
  return (
    <>
      <>
        <div
          style={{
            width: "64px",
            height: "64px",
            background: state.color
          }}
        />
        <div
          style={{
            width: "32px",
            height: "32px",
            background: state.subcolor
          }}
        />
      </>
    </>
  );
};

export default ColorBox;

🧐 정보

Function as a child, Render Props

  • 컴포넌트의 children이 있어야 할 자리에 JSX 혹은 문자열이 아닌 함수를 전달하는 것
profile
자바스크립트와 파이썬 그리고 컴퓨터와 네트워크

0개의 댓글