mingg IT

[React] Context API 본문

FrontEnd

[React] Context API

mingg123 2020. 12. 8. 21:57

리액트 프로젝트 내에 전역적으로 관리할 데이터가 있을 때 Context API를 사용한다.

 

예를 들면 사용자 로그인 정보, 애플리케이션 환경 설정, 테마 등

 

리액트 라이브러리로 리덕스, 리액트 라우터, styled-components 도 Context API를 기반으로 구현되어 있음

 

전역적으로 관리할 데이터는 주로 최상위 컴포넌트인 App의 state에 넣어서 관리함

 

예제)

마우스 클릭에 따라 색상 바뀌는것

 

왼쪽은 큰 정사각형, 오른쪽은 작은 정사각형 색이 변함

 

오른쪽 마우스 클릭은 onContextMenu를 사용! 왼쪽 마우스는 OnClick 

 

components/ColorBox.js

 

import React from "react";

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

 

const ColorBox = () => {

return (

<ColorConsumer>

{(value) => (

<>

<div

style={{

width: "64px",

height: "64px",

background: value.state.color,

}}

/>

<div

style={{

width: "32px",

height: "32px",

background: value.state.subcolor,

}}

/>

</>

)}

</ColorConsumer>

);

};

export default ColorBox;

 

components/SelectColor.js

 

import React from "react";

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

 

const colors = ["red", "orange", "yellow", "green", "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>

<hr />

</div>

);

};

export default SelectColors;

 

 

contexts/color.js

 

import { createContext } from "react";

import React, { 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 logo from "./logo.svg";

import "./App.css";

import ColorBox from "./components/ColorBox";

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

import SelectColors from "./components/SelectColor";

 

function App() {

return (

<ColorProvider>

<div>

<SelectColors />

<ColorBox />

</div>

</ColorProvider>

);

}

 

export default App;

 

useContext Hook 사용

 

components/ColorBox.js

 

import React, { useContext } from "react";

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

import { ColorConsumer } 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;

 

 

클래스형 컴포넌트로 static contextType 사용

장점 : 클래스 메서드에서도 Context에 넣어 둔 함수를 호출할 수 있다. 

단점 : 한 클래스에서 하나의 Context밖에 사용하지 못한다.

useContext사용을 권장 

 

components/SelectColor.js 

import React, { Component } from "react";

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

 

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

 

class SelectColors extends Component {

static contextType = ColorContext;

 

handleSetColor = (color) => {

this.context.actions.setColor(color);

};

 

handleSetSubcolor = (subcolor) => {

this.context.actions.setSubcolor(subcolor);

};

 

render() {

return (

<div>

<h2> 색상을 선택하세요.</h2>

<div style={{ display: "flex" }}>

{colors.map((color) => (

<div

key={color}

style={{

background: color,

width: "24px",

height: "24px",

cursor: "pointer",

}}

onClick={() => this.handleSetColor(color)}

onContextMenu={(e) => {

e.preventDefault();

this.handleSetSubcolor(color);

}}

/>

))}

</div>

<hr />

</div>

);

}

}

export default SelectColors;

 

Comments