π γμνμ μ²μ λ§λ 리μ‘νΈγ
λ₯Ό μ½κ³ μ 리ν κΈμ
λλ€.
Context
Context
λ κΈ°μ‘΄μ props
λ₯Ό ν΅ν΄ React Component
λ€ μ¬μ΄μμ λ°μ΄ν°λ₯Ό μ λ¬νλ λ°©μ λμ Component
νΈλ¦¬λ₯Ό ν΅ν΄ κ³§λ°λ‘ Component
μ μ λ¬νλ μλ‘μ΄ λ°©μμ μ 곡νλ€.- κΈ°μ‘΄ λ°©μμ κ²½μ° νμ
Component
λ‘ λ°μ΄ν°λ₯Ό μ λ¬νλ €λ©΄ νΈλ¦¬λ₯Ό νκ³ λͺ λ²μ λ΄λ €κ°λ©° μ λ¬μ ν΄μΌνμ§λ§, Context
λ₯Ό μ¬μ©νλ€λ©΄ λ°μ΄ν°λ₯Ό νμλ‘ νλ Component
μ κ³§λ°λ‘ λ°μ΄ν°λ₯Ό μ λ¬ν μ μλ€.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| function App(props) {
return <Toolbar theme="dark"/>;
}
function Toolbar(props) {
return (
<div>
<ThemeButton theme={props.theme}/>
</div>
);
}
function ThemeButton(props) {
return <Button theme={props.theme}/>;
}
|
Context
λ₯Ό μ μ©νμ§ μμ μ½λμ΄λ€.- μ΄λ κ² μ²λ¦¬νλ©΄ λ°λ³΅λ μ½λλ₯Ό κ³μ μμ±ν΄μ£Όμ΄μΌ νκΈ° λλ¬Έμ λΉν¨μ¨μ μ΄κ³ μ§κ΄μ μ΄μ§λ μλ€.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
| const ThemeContext = React.createContext('light');
function App(props) {
return (
<ThemeContext.Provider value="dark">
<Toolbar/>
</ThemeContext.Provider>
);
}
function Toolbar(props) {
return (
<div>
<ThemeButton />
</div>
);
}
function ThemeButton(props) {
return (
<ThemeContext.Consumer>
{value => <Button theme={value}/>}
</ThemeContext.Consumer>
);
}
|
μμ Context
λ₯Ό Provider
λ‘ κ°μΈλ©΄ λͺ¨λ νμ Context
κ° μΌλ§λ κΉμ΄ μμΉν΄ μλμ§ κ΄κ³μμ΄ Context
μ λ°μ΄ν°λ₯Ό μ½μ μ μλ€.
Context
μ¬μ© μ μ£Όμν μ
- 무쑰건
Context
λ₯Ό μ¬μ©νλ κ²μ μ³μ§ μλ€. Component
μ Context
κ° μ°λλλ©΄ μ¬μ¬μ©μ±μ΄ λ¨μ΄μ§κΈ° λλ¬Έμ΄λ€.- λ€λ₯Έ λ 벨μ λ§μ
Component
κ° λ°μ΄ν°λ₯Ό νμλ‘ νλ κ²½μ°κ° μλλΌλ©΄ κΈ°μ‘΄μ μ¬μ©νλ λ°©μλλ‘ props
λ₯Ό ν΅ν΄ λ°μ΄ν°λ₯Ό μ λ¬νλ Component
Composition
λ°©μμ΄ λ μ ν©νλ€.
Context
λμ Element
λ³μ νν
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| function Page(props) {
const user = props.user;
const userLink = (
<Link href={user.peralink}>
<Avatar user={user} size={props.avatarSize}/>
</Link>
);
return <PageLayout userLink={userLink}/>
}
// NavigationBar μ»΄ν¬λνΈλ₯Ό λ λλ§
<PageLayout userLink={...}/>
// propsλ‘ μ λ¬λ°μ userLink μ리먼νΈλ₯Ό λ°ν
<NavigationBar userLink={...}/>
|
- μ΅μμ
Component
μμ Avatar
Component
λ₯Ό λ³μμ μ μ₯νμ¬ μ§μ λ겨주면 μ€κ° Component
λ€μ user
μ avatarSize
μ λν΄ λͺ°λΌλ λλ€. - μ΄λ μ΅μμ
Component
μ μ’ λ λ§μ κΆνμ λΆμ¬ν΄μ€λ€. - κ·Έλ¬λ λ°μ΄ν°κ° λ§μμ§μλ‘ μμ
Component
μ μ½λκ° λͺ°λ¦¬κΈ° λλ¬Έμ 볡μ‘ν΄μ§κ³ , νμ Component
λ λ무 μ μ°ν΄μ§λ€λ λ¨μ μ΄ μλ€.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| function Page(props) {
const user = props.user;
const topBar = (
<NavigationBar>
<Link href={user.peralink}>
<Avatar user={user} size={props.avatarSize}/>
</Link>
</NavigationBar>
);
const content = <Feed user={user}>
return (
<PageLayout
topBar={topBar}
content={content}
/>
);
}
|
μ΄ λ°©μμ νμ Component
μ μμ‘΄μ±μ μμ Component
μ λΆλ¦¬ν νμκ° μλ λλΆλΆμ κ²½μ°μ μ ν©ν λ°©λ²μ΄λ€.
Context API
μ’
λ₯
β
React.createContext
1
| const MyContext = React.createContext(κΈ°λ³Έκ°);
|
React
μμ λ λλ§μ΄ μΌμ΄λ λ Context
κ°μ²΄λ₯Ό ꡬλ
νλ νμ Component
κ° λμ€λ©΄ νμ¬ Context
κ°μ κ°μ₯ κ°κΉμ΄μ μλ μμ λ 벨μ Provider
λ‘λΆν° λ°μμ€κ² λλ€.- μμ λ 벨μ λ§€μΉλλ
Provider
κ° μλ€λ©΄ μ΄ κ²½μ°μλ§ κΈ°λ³Έ κ°μ΄ μ μ©λλ€. - κΈ°λ³Έ κ°μ
undefined
λ₯Ό λ£μΌλ©΄ κΈ°λ³Έ κ°μ΄ μ¬μ©λμ§ μλλ€.
β
Context.Provider
1
| <MyContext.Provider value={/* νΉμ κ° */}/>
|
Context
λ₯Ό λ§λ€μλ€λ©΄ νμ Component
λ€μ΄ ν΄λΉ Context
μ λ°μ΄ν°λ₯Ό λ°μ μ μλλ‘ μ€μ ν΄ μ€μΌ νλ€.- λͺ¨λ
Component
λ Provider
λΌλ React Component
λ₯Ό κ°κ³ μλ€. - Context.Providerλ‘ μμ
Component
λ₯Ό κ°μΈλ©΄ λͺ¨λ νμ Component
λ€μ΄ ν΄λΉ Context
λ°μ΄ν°μ μ κ·Όν μ μκ² λλλ°, μ΄λ¬ν νμ Component
λ€μ Consumer
Component
λΌκ³ λΆλ₯Έλ€. - λͺ¨λ Consumer
Component
μ Provider
μ value prop
μ΄ λ°λ λλ§λ€ λ λλ§λλ€. - κ°μ΄ λ³κ²½λμμ λ μμ
Component
κ° Update
λμμ΄ μλλλΌλ νμ Component
κ° Context
λ₯Ό μ¬μ©νλ€λ©΄ νμ Component
μμλ Update
κ° μΌμ΄λλ€. - κ°μ λ³νλ₯Ό νλ¨νλ κΈ°μ€μ
Object.is()
λΌλ ν¨μμ κ°μ λ°©μμΌλ‘ νλ¨νλ€.
β
Class.contextType
1
| MyClass.contextType = MyContext;
|
Provider
νμμ μλ Class Component
μμ Context
μ λ°μ΄ν°μ μ κ·ΌνκΈ° μν΄ μ¬μ©νλ κ²μ΄λ€.Class Component
λ νμ¬ κ±°μ μ¬μ©νμ§ μκΈ° λλ¬Έμ μ°Έκ³ λ§ νλ©΄ λλ€.- μκΈ° μ½λμ κ°μ΄ μμ±νλ©΄
MyClass
Component
λ MyContext
μ λ°μ΄ν°μ μ κ·Όν μ μκ² λλ€. - μ΄
API
λ λ¨ νλμ Context
λ§μ ꡬλ
ν μ μλ€.
β
Context.Consumer
1
2
3
| <MyContext.Consumer>
{value => /* 컨ν
μ€νΈ κ°μ λ°λΌμ μ»΄ν¬λνΈ λ λλ§ */}
</MyContext.Consumer>
|
Context
μ λ°μ΄ν°λ₯Ό ꡬλ
νλ Component
μ΄λ€.Component
μ μμμΌλ‘ ν¨μκ° μ¬ μ μλλ° μ΄κ²μ function as a child
λΌκ³ νλ€.Context.Consumer
λ‘ κ°μΈλ©΄ μμμΌλ‘ λ€μ΄κ° ν¨μκ° νμ¬ Context
μ value
λ₯Ό λ°μμ React
λ
Έλλ‘ λ°ννλ€.
β
Context.displayName
1
2
3
4
5
6
7
| const MyContext = React.createContext(/* some value*/);
// κ°λ°μ λꡬμ MyDisplayName.Providerλ‘ νμλ¨
<MyContext.Provider/>
// κ°λ°μ λꡬμ MyDisplayName.Consumerλ‘ νμλ¨
<MyContext.Consumer/>
|
Context
κ°μ²΄λ displayName
μ΄λΌλ λ¬Έμμ΄ μμ±μ κ°μ§λ€.Chrome
μ κ°λ°μ λꡬμμλ μ΄ displayName
λ₯Ό κ°μ΄ νμν΄μ€λ€.
β
μ¬λ¬ Context
μ¬μ©
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
| const ThemeContext = React.createContext('light');
const UserContext = React.createContext({
name: 'Guest',
});
class App extends React.Component {
render() {
const { signedInUser, theme } = this.props;
return (
<ThemeContext.Provider value={theme}>
<UserContext.Provider value={signedInUser}>
<Layout />
</UserContext.Provider>
</ThemeContext.Provider>
);
}
}
function Layout() {
return (
<div>
<Sidebar />
<Content />
</div>
)
}
function Content() {
return (
<ThemeContext.Consumer>
{theme => (
<UserContext.Consumer>
{user => (
<ProfilePage user={user} theme={theme} />
)}
</UserContext.Consumer>
)}
</ThemeContext.Consumer>
);
}
|
- μ¬λ¬ κ°μ
Context
λ₯Ό λμμ μ¬μ©νλ €λ©΄ Context.Provider
λ₯Ό μ€μ²© ν΄μ μ¬μ©νμ¬ κ΅¬νν μ μλ€. - νμ§λ§ λ κ° λλ κ·Έ μ΄μμ
Context
κ°μ΄ ν¨κ» μ¬μ©λ κ²½μ° λͺ¨λ κ°μ ν λ²μ μ 곡ν΄μ£Όλ λ³λμ render prop
Component
λ₯Ό μ§μ λ§λλ κ²μ κ³ λ €νλ κ²μ΄ μ’λ€.
β
useContext
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| function MyComponent(props) {
const value = useContext(MyContext);
return (
// ...
);
}
// μ¬λ°λ₯Έ μ¬μ©λ²
useContext(MyContext);
// μλͺ»λ μ¬μ©λ²
useContext(MyContext.Consumer);
useContext(MyContext.Provider);
|
Functional Component
μμλ Context
λ₯Ό μ¬μ©νκΈ° μν΄ Component
λ₯Ό λ§€λ² Consumer
Component
λ‘ κ°μΈμ£Όλ κ²λ³΄λ€ λ μ’μ λ°©λ²μ΄ μλ€.- λ°λ‘
useContext()
Hook
μ΄λ€. - ν΄λΉ
Hook
μ React.createContext()
ν¨μ νΈμΆλ‘ μμ±λ Context
κ°μ²΄λ₯Ό μΈμλ‘ λ°μμ νμ¬ Context
μ κ°μ λ°ννλ€. useContext()
Hook
μ λ€λ₯Έ λ°©μκ³Ό λμΌνκ² Component
νΈλ¦¬ μμμ κ°μ₯ κ°κΉμ΄ μμ Provider
λ‘λΆν° Context
μ κ°μ λ°μμ€κ² λλ€.- λ§μ½
Context
μ κ°μ΄ λ³κ²½λλ©΄ λ³κ²½λ κ°κ³Ό ν¨κ» useContext()
Hook
μ μ¬μ©νλ Component
κ° λ λλ§ λλ€. - κ·Έλ¬λ―λ‘ ν΄λΉ
Hook
μ μ¬μ©νλ Component
μ λ λλ§μ΄ λ¬΄κ±°μ΄ μμ
μΌ κ²½μ°μλ λ³λλ‘ μ΅μ ν μμ
μ ν΄μ£Όμ΄μΌ νλ€. useContext()
Hook
μ μ¬μ©ν λμλ νλΌλ―Έν°λ‘ Context
κ°μ²΄λ₯Ό λ£μ΄μ€μΌ νλ€.
μ€μ΅
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
| // ThemeContext.jsx
const ThemeContext = React.createContext();
ThemeContext.displayName = "ThemeContext";
export default ThemeContext;
// MainContent.jsx
function MainContent(props) {
const { theme, toggleTheme } = useContext(ThemeContext);
return (
<div
style=>
<p>μλ
νμΈμ, ν
λ§ λ³κ²½μ΄ κ°λ₯ν μΉμ¬μ΄νΈ μ
λλ€.</p>
<button onClick={toggleTheme}>ν
λ§ λ³κ²½</button>
</div>
);
}
export default MainContent;
// DarkOrLight.jsx
function DarkOrLight(props){
const [theme, setTheme] = useState("light")
const toggleTheme = useCallback(() => {
if (theme == "light") {
setTheme("dark");
} else if (theme == "dark") {
setTheme("light");
}
},[theme]);
return (
<ThemeContext.Provider value={/*{theme, toggleTheme}*/}>
<MainContent />
</ThemeContext.Provider>
);
}
export default DarkOrLight;
|
Context API
λ₯Ό μ΄μ©ν μ μ μν κ΄λ¦¬λ₯Ό μννλ€.
νκ³
- μ¬λ¬
Component
μμ 곡ν΅μΌλ‘ μ¬μ©νλ λ°μ΄ν°λ Context
λ‘ κ΄λ¦¬νλ©΄ props drilling
μμ΄ κΉλνκ² ν΄κ²° κ°λ₯νλ€λ μ μ μκ² λμλ€.