목차
// contexts/color.js
import {createContext} from 'react';
const ColorContext = createContext({color:'black'});
export default ColorContext;
{value => ()}
)를 넣었다. 이런 패턴을 Function as a child 혹은 Render Props라고 한다. 컴포넌트의 children이 있어야할 자리에 일반 JSX 혹은 문자열이 아닌 함수를 전달한다.// components/CorlorBox.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;
import React from 'react';
import ColorBox from './components/ColorBox';
const App = () => {
return (
<div>
<ColorBox />
</div>
);
};
export deafult App;
- 참고: Render Props 예제
import React from 'react';
const RenderPropsSample = ({children}) => {
return <div>결과: {children(5)} </div>;
}
export default RenderPropsSample;
위의 컴포넌트는 다음과 같이 사용 가능하다.
<RnderPropsSample>{value => 2*value}</RenderPropsSample>;
import React from 'react';
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;
// contexts/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 Colorconsumer = ColorContext.Consumer
const { Consumer: ColorConsumer } = ColorContext;
// ColorProvider와 ColorConsumber 내보내기
export { ColorProvider, ColorConsumer };
export default ColorContext;
const {Consumer: ColorConsumer} = ColorContext
비구조화 할당 이해 안됨
2) 새로워진 Context를 프로젝트에 반영하기
// App.js
import React from "react";
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;
// App.js
import React from "react";
import ColorBox from "./components/ColorBox";
import { ColorProvider } from "./contexts/color";
const App = () => {
return (
<ColorProvider value={{ color: "red" }}>
<div>
<SelectColors />
</div>
</ColorProvider>
);
};
export default App;
// 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/SelectColors.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",
curor: "pointer",
}}
onClick={() => actions.setColor(color)}
onContextMenu={(e) => {
e.preventDefault();
actions.setSubcolor(color);
}}
/>
))}
</div>
)}
</ColorConsumer>
<hr />
</div>
);
};
export default SelectColors;
// App.js
import React from "react";
import ColorBox from "./components/ColorBox";
import { ColorProvider } from "./contexts/color";
import SelectColors from "./components/SelectColors";
const App = () => {
return (
<ColorProvider value={{ color: "red" }}>
<div>
<SelectColors />
<ColorBox />
</div>
</ColorProvider>
);
};
export default App;
// components/ColorBox.js
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;
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;