์ ์ญ์ผ๋ก ์ฌ์ฉํ ๋ฐ์ดํฐ๊ฐ ์์ ๋ ์ ์ฉํ ๊ธฐ๋ฅ
์์) ์ฌ์ฉ์ ๋ก๊ทธ์ธ ์ ๋ณด, ์ ํ๋ฆฌ์ผ์ด์
ํ๊ฒฝ ์ค์ , ํ
๋ง React 16.3๋ถํฐ ์ฌ์ฉ๊ฐ๋ฅ
Redux, React Roter, styled-componrnts ๋ผ์ด๋ธ๋ฌ๋ฆฌ์์ Context API ๊ธฐ๋ฐ์ผ๋ก ๊ตฌํ๋์ด ์๋ค.
Redux๋ MobX ๊ฐ์ ์ํ ๊ด๋ฆฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ์ฌ ์ ์ญ ์ํ ๊ด๋ฆฌ ์์
์ ๋ ํธ๋ฆฌํ๊ฒ ํ๊ธฐ๋ ํ์ง๋ง, React v16.3 ์
๋ฐ์ดํธ ์ดํ์๋ ๋ณ๋์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ์ง ์์๋ ์ ์ญ ์ํ๋ฅผ ์์ฝ๊ฒ ๊ด๋ฆฌ ํ ์ ์๋ค.
constexts/color.js
createContext
์ Context๋ฅผ ๋ง๋ค๋ createContext๋ฅผ ์ฌ์ฉํ๋ค.
import { createContext } from 'react';
const ColorContext = createContext({ color: 'black' });
export default ColorContext;
Consumer
ColorBox Component: ColorContext ์์ ๋ค์ด ์๋ ์์์ ๋ณด์ฌ์ค props๋ก ๋ฐ์ ์ค๋ ๊ฒ์ด ์๋๋ผ ColorContext ์์ ๋ค์ด ์๋ Consumer๋ผ๋ ์ปดํฌ๋ํธ๋ฅผ ํตํด ์์ ์กฐํ
src/components/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;
์์ ํจ์๋ฅผ ๋ฃ์ด์ฃผ๋ ํจํด์ Function as a child
ํน์ Render Props
๋ผ๊ณ ํ๋ค. ์ปดํฌ๋ํธ์ children์ด ์์ด์ผ ํ ์๋ฆฌ์ ํจ์๋ฅผ ์ ๋ฌํ๋ค.
Function as a child or Render Props
import React from 'react';
const RenderPropsSample = ({ children }) => {
return <div>๊ฒฐ๊ณผ: {childern(5)}</div>;
};
// ๋ง์ฝ ์์ ๊ฐ์ ์ปดํฌ๋ํธ๊ฐ ์๋ค๋ฉด ์ถํ ์ฌ์ฉํ ๋ ๋ค์๊ณผ ๊ฐ์ด ์ฌ์ฉํ ์ ์๋ค.
<RenderPropsSample>{value => 2 * value}</RenderPropsSample>
children์ ํจ์๋ก ๋ณด๋ผ ์ ์๊ตฌ, ์ธ์๊ฐ์ ํตํด ์ํ๋ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ์ ์ ์๊ตฌ๋. ํ?!
children์ ํจ์๋ผ ์๊ฐํ๋ ์ดํดํ๊ธฐ ์ฌ์์ก๋.
Provider
Context์ value๊ฐ์ ๋ณ๊ฒฝํ ์ ์๋ค.
function App() {
return (
<ColorContext.Provider value={{ color: "red" }}>
<div>
<ColorBox />
</div>
</ColorContext.Provider>
);
}
const ColorContext = createContext({ color: "black" });
Provider๋ฅผ ์ฌ์ฉํ์ง ์์ ๋ ๊ธฐ๋ณธ๊ฐ
Provider๋ฅผ ์ฌ์ฉํ ๋๋ value๋ฅผ ๊ผญ ๋ช
์ํด์ค์ผ ํ๋ค.
๋์ Context ์ฌ์ฉ
contexts/color.js ์์
import React, { createContext, useState } from "react";
// ์ Context๋ฅผ ๋ง๋ค๋ createContext๋ฅผ ์ฌ์ฉํ๋ค.
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๋ฅผ ๋ ๋๋งํ๋ค.
App.js์ ColorProvider์ฌ์ฉ
import { ColorProvider } from "./contexts/color";
function App() {
return (
<ColorProvider>
<div>
<ColorBox />
</div>
</ColorProvider>
);
}
export default App;
ColorBox ์ปดํฌ๋ํธ์ ColorConsumer ์ฌ์ฉ
ํ๋ ์ ํ
์ด์
์ปดํฌ๋ํธ์ด๋ Consumer์ฌ์ฉ
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>
);
};
๊ฐ์ฒด ๋น๊ตฌ์กฐํ ํ๋น ๋ฌธ๋ฒ์ ์ฌ์ฉํ์ฌ value์์ state๋ง ์กฐํ
selectBox ์ถ๊ฐ
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;
actions: {
setColor: () => {},
setSubcolor: () => {}
}
์ฒ์์ ์ด ๋ถ๋ถ์ด ์ดํด๊ฐ ์๊ฐ๋๋ฐ, ๊ทธ๋ฅ ์ด ์๋ฆฌ์ ํจ์๊ฐ ์ฌ ๊ฑฐ๋ผ๋ ๋ป์ด์๋ค.
onContextMenu()๋ ๋ง์ฐ์ค ์ค๋ฅธ์ชฝ ํด๋ฆญํ์๋ ์ฌ์ฉ
useContext Hook ์ฌ์ฉํ๊ธฐ
context๋ฅผ ์ฌ์ฉํ๋ ์ฝ๋์์
<ColorConsumer>
{({ state }) => (
// code
)}
</ColorConsumer>
ColorConsumer ์ปดํฌ๋ํธ๋ค ์ง์ฐ๊ณ
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
}}
/>
</>
);
};
์์ฃผ ๊ฐ๋ณ๊ณ ๊ฐ๋จํ๊ฒ ์ฌ์ฉ๊ฐ๋ฅ
Class Component์์ static contextType ์ฌ์ฉํ๊ธฐ
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>
);
}
}
static contextType = ColorContext;
Class Component์์๋ static contextType์ ์ด์ฉํ์ฌ Context๋ฅผ ์ฌ์ฉํ ์ ์์ง๋ง ๋จ์ ์ ํ class ์ปดํฌ๋ํธ๋น ํ๋์ Context๋ฐ์ ์ฌ์ฉ๋ชปํ๋ค.. ๐
์ ๋ฆฌ
๋จ์ํ ์ ์ญ ์ํ ๊ด๋ฆฌ๋ ๋ฆฌ๋์ค ๋์ ์ Context API๋ก ๋์ฒด ํ ์ ์๋ค. ํ์ง๋ง ๋ฆฌ๋์ค๋ ๋์ฑ ํฅ์๋ ์ฑ๋ฅ๊ณผ ๋ฏธ๋ค์จ์ด ๊ธฐ๋ฅ, ๊ฐ๋ ฅํ ๊ฐ๋ฐ์ ๋๊ตฌ, ์ฝ๋์ ๋์ ์ ์ง ๋ณด์์ฑ์ ์ ๊ณต..