Context API

nara_lee·2025년 3월 17일
0

Context API 사용법

Create New Context

// contexts/color.js
import { createContext } from "react";

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

Consumer

// components/ColorBox.js
import ColorContext from "../contexts/color";
const ColorBox = () => {
  <ColorContext.Consumer>
    {(value) => (
      <div
        style={{
          width: "64px",
          height: "64px",
          background: value.color,
        }}
      />
    )}
  </ColorContext.Consumer>;
};
export default ColorBox;

Render Props (aka Function as a child)
예시

<RenderPropsSample>{value => 2 * value}<RenderPropsSample/>

그럼 RenderPropsSample은 함수인 children을 부른다.

const RenderPropsSample = ({children}) => {
  return <div>{children(5)}</div>;
}
export default RenderPropsSample;

.
우리의 예제에서는 ColorContext.Consumer라는 component의 child가 function인 것!

// ColorContext
const ColorContext = createContext({ color: "black" });
// ColorBox Function Component의 Function Statement ()=>{요거}
  <ColorContext.Consumer>
    {(value) => (<div style={{(...)background: value.color,}}/>)}
  </ColorContext.Consumer>;

ColorContext.Consumer의 function definition 에서 createContext에서 만든 context 객체를 argument로 다음과 같이 넣어서 children({ color: "black" }) 부르는 원리인 듯.

Provider

Provider 사용하면 Context의 value를 해당 컴포넌트 안에서 변경 가능하다.

// App.js
import ColorBox from "./components/ColorBox";
import ColorContext from "./contexts/color";

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

export default App;
  • ⚠️ Provider 사용할 때 무조건 value attribute 있어야 됨. 안그럼 runtime error.
  • 이렇게 쓰면 해당 Provider안에서만 color:"red"가 적용되는 것이지 context 자체 내용이 변하지는 않는다.

Dynamic Context 사용하기

Context 생성, Customized Provider & Consumer 정의

// 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 ColorConsumer = ColorContext.Consumer; 와 같은 의미
const { Consumer: ColorConsumer } = ColorContext;

export { ColorProvider, ColorConsumer };

export default ColorContext;

Consumer 사용

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

const ColorBox = () => {
  return (
    <ColorConsumer>
      {(
        { state } //`{(value) => (` 객체비구조화 할당으로 value 대신 그의 하위 객체인 state을 받아옴
      ) => (
        <>
          <div
            style={{
              width: "64px",
              height: "64px",
              background: state.color, //value.state.color,
            }}
          />
          <div
            style={{
              width: "32px",
              height: "32px",
              background: state.subcolor, //value.state.subcolor,
            }}
          />
        </>
      )}
    </ColorConsumer>
  );
};
export default ColorBox;

Event Listener로 Context에 있는 state 바꾸기

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

const ColorBox = () => {
  return (
    <ColorConsumer>
      {(
        { state } //`{(value) => (` 객체비구조화 할당으로 value 대신 그의 하위 객체인 state을 받아옴
      ) => (
        <>
          <div
            style={{
              width: "64px",
              height: "64px",
              background: state.color, //value.state.color,
            }}
          />
          <div
            style={{
              width: "32px",
              height: "32px",
              background: state.subcolor, //value.state.subcolor,
            }}
          />
        </>
      )}
    </ColorConsumer>
  );
};
export default ColorBox;

App.js

// App.js
import ColorBox from "./components/ColorBox";
import SelectColors from "./components/SelectColors";
import { ColorProvider } from "./contexts/color";

const App = () => {
  return (
    <>
      <ColorProvider>
        <div>
          <SelectColors/>
          <ColorBox />
        </div>
      </ColorProvider>
    </>
  );
};

export default App;

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

Function Component: useContext Hook 사용

// Before
const ColorBox = () => {
  return (
    <ColorConsumer>
      {({ state }) => (
        <>(...)</>
// After
const ColorBox = () => {
  const { state } = useContext(ColorContext);
  return (
    <>(...)</>

⚠️ Hook은 함수 컴포넌트 안에서만 사용가능

Class Component: static contextType 사용

// 클래스형 컴포넌트 버전의 SelectColors.js
class SelectColors extends Component {
	static contextType = ColorContext;
	handleSetColor = color => {
    	this.context.actions.setColor(color);
    }
	handleSetSubcolor = subcolor => {
    	this.context.actions.setSubcolor(subColor);
    }
	render(){
    	return(
        	<div>
            (...)
            	onClick{() => this.handleSetColor(color)}
            	onContextMenu{e => {
            		e.preventDefault();
              		this.handleSetSubcolor(color);
            	}}
          	</div>
        ) 
    }
}

0개의 댓글