Skip to content

Commit f7093f8

Browse files
committed
[React]Context 와 Provider 복습
1 parent dddfb5f commit f7093f8

File tree

3 files changed

+217
-0
lines changed

3 files changed

+217
-0
lines changed

example/hook/Context-ex.jsx

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
import { createContext, useContext, useState } from "react";
2+
3+
const ThemeContext = createContext(null);
4+
const CurrentUserContext = createContext(null);
5+
6+
export default function MyApp() {
7+
const [theme, setTheme] = useState("light");
8+
const [currentUser, setCurrentUser] = useState(null); // 이 부분을 Provider 로 분리(ex2)
9+
return (
10+
<ThemeContext value={theme}>
11+
<CurrentUserContext
12+
value={{
13+
currentUser,
14+
setCurrentUser,
15+
}}
16+
>
17+
<WelcomePanel />
18+
<label>
19+
<input
20+
type="checkbox"
21+
checked={theme === "dark"}
22+
onChange={(e) => {
23+
setTheme(e.target.checked ? "dark" : "light");
24+
}}
25+
/>
26+
Use dark mode
27+
</label>
28+
</CurrentUserContext>
29+
</ThemeContext>
30+
);
31+
}
32+
33+
function WelcomePanel({ children }) {
34+
const { currentUser } = useContext(CurrentUserContext);
35+
return (
36+
<Panel title="Welcome">
37+
{currentUser !== null ? <Greeting /> : <LoginForm />}
38+
</Panel>
39+
);
40+
}
41+
42+
function Greeting() {
43+
const { currentUser } = useContext(CurrentUserContext);
44+
return <p>You logged in as {currentUser.name}.</p>;
45+
}
46+
47+
function LoginForm() {
48+
const { setCurrentUser } = useContext(CurrentUserContext);
49+
const [firstName, setFirstName] = useState("");
50+
const [lastName, setLastName] = useState("");
51+
const canLogin = firstName.trim() !== "" && lastName.trim() !== "";
52+
return (
53+
<>
54+
<label>
55+
First name{": "}
56+
<input
57+
required
58+
value={firstName}
59+
onChange={(e) => setFirstName(e.target.value)}
60+
/>
61+
</label>
62+
<label>
63+
Last name{": "}
64+
<input
65+
required
66+
value={lastName}
67+
onChange={(e) => setLastName(e.target.value)}
68+
/>
69+
</label>
70+
<Button
71+
disabled={!canLogin}
72+
onClick={() => {
73+
setCurrentUser({
74+
name: firstName + " " + lastName,
75+
});
76+
}}
77+
>
78+
Log in
79+
</Button>
80+
{!canLogin && <i>Fill in both fields.</i>}
81+
</>
82+
);
83+
}
84+
85+
function Panel({ title, children }) {
86+
const theme = useContext(ThemeContext);
87+
const className = "panel-" + theme;
88+
return (
89+
<section className={className}>
90+
<h1>{title}</h1>
91+
{children}
92+
</section>
93+
);
94+
}
95+
96+
function Button({ children, disabled, onClick }) {
97+
const theme = useContext(ThemeContext);
98+
const className = "button-" + theme;
99+
return (
100+
<button className={className} disabled={disabled} onClick={onClick}>
101+
{children}
102+
</button>
103+
);
104+
}

example/hook/Context-ex2.jsx

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
import { createContext, useContext, useState } from "react";
2+
3+
const ThemeContext = createContext(null);
4+
const CurrentUserContext = createContext(null);
5+
6+
export default function MyApp() {
7+
const [theme, setTheme] = useState("light");
8+
return (
9+
<MyProviders theme={theme} setTheme={setTheme}>
10+
<WelcomePanel />
11+
<label>
12+
<input
13+
type="checkbox"
14+
checked={theme === "dark"}
15+
onChange={(e) => {
16+
setTheme(e.target.checked ? "dark" : "light");
17+
}}
18+
/>
19+
Use dark mode
20+
</label>
21+
</MyProviders>
22+
);
23+
}
24+
25+
function MyProviders({ children, theme, setTheme }) {
26+
const [currentUser, setCurrentUser] = useState(null);
27+
return (
28+
<ThemeContext value={theme}>
29+
<CurrentUserContext
30+
value={{
31+
currentUser,
32+
setCurrentUser,
33+
}}
34+
>
35+
{children}
36+
</CurrentUserContext>
37+
</ThemeContext>
38+
);
39+
}
40+
41+
function WelcomePanel({ children }) {
42+
const { currentUser } = useContext(CurrentUserContext);
43+
return (
44+
<Panel title="Welcome">
45+
{currentUser !== null ? <Greeting /> : <LoginForm />}
46+
</Panel>
47+
);
48+
}
49+
50+
function Greeting() {
51+
const { currentUser } = useContext(CurrentUserContext);
52+
return <p>You logged in as {currentUser.name}.</p>;
53+
}
54+
55+
function LoginForm() {
56+
const { setCurrentUser } = useContext(CurrentUserContext);
57+
const [firstName, setFirstName] = useState("");
58+
const [lastName, setLastName] = useState("");
59+
const canLogin = firstName !== "" && lastName !== "";
60+
return (
61+
<>
62+
<label>
63+
First name{": "}
64+
<input
65+
required
66+
value={firstName}
67+
onChange={(e) => setFirstName(e.target.value)}
68+
/>
69+
</label>
70+
<label>
71+
Last name{": "}
72+
<input
73+
required
74+
value={lastName}
75+
onChange={(e) => setLastName(e.target.value)}
76+
/>
77+
</label>
78+
<Button
79+
disabled={!canLogin}
80+
onClick={() => {
81+
setCurrentUser({
82+
name: firstName + " " + lastName,
83+
});
84+
}}
85+
>
86+
Log in
87+
</Button>
88+
{!canLogin && <i>Fill in both fields.</i>}
89+
</>
90+
);
91+
}
92+
93+
function Panel({ title, children }) {
94+
const theme = useContext(ThemeContext);
95+
const className = "panel-" + theme;
96+
return (
97+
<section className={className}>
98+
<h1>{title}</h1>
99+
{children}
100+
</section>
101+
);
102+
}
103+
104+
function Button({ children, disabled, onClick }) {
105+
const theme = useContext(ThemeContext);
106+
const className = "button-" + theme;
107+
return (
108+
<button className={className} disabled={disabled} onClick={onClick}>
109+
{children}
110+
</button>
111+
);
112+
}

example/reducer.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[도움](https://ko.react.dev/learn/scaling-up-with-reducer-and-context)

0 commit comments

Comments
 (0)