React 2์ฃผ์ฐจ ์ ๋ฆฌ
์ด ๊ธ์ ๋ชฉ์ฐจ80๊ฐ
- โ ์กฐ๊ฑด๋ถ ๋ ๋๋ง์ ์ฌ์ฉ
- ๐ ์กฐ๊ฑด๋ถ ๋ ๋๋ง ๋ฐฉ์
- 1. if ๋ฌธ ์ฌ์ฉ
- 2. ์ผํญ ์ฐ์ฐ์ ์ฌ์ฉ (Inline ์กฐ๊ฑด)
- 3. && ์ฐ์ฐ์ ์ฌ์ฉ
- โ ์ฃผ์์ฌํญ: false, null, undefined๋ ๋ ๋๋ง๋์ง ์์
- โจ ์์ : ๋ก๊ทธ์ธ ๋ฒํผ ์ ํ
- โญ๏ธ ์์ฝ
- โ ๋ฆฌ์คํธ ๋ ๋๋ง์ด๋?
- ๐ ์์ : ๋ฐฐ์ด์ ํ๋ฉด์ ์ถ๋ ฅํ๊ธฐ
- ๐ Key๋?
- โ key์ index๋ฅผ ์ฌ์ฉํด๋ ๋ ๊น?
- โญ๏ธ ์์ฝ
- โ ์ Controlled Component๋ฅผ ์ฌ์ฉํ ๊น?
- โ๏ธ Controlled Component ๊ธฐ๋ณธ ์์
- โ ๋ค์ํ Form ์์๋ค ์ ์ดํ๊ธฐ
- ๐ textarea ์ ์ด
- ๐ select ์ ์ด
- โ ์ฃผ์ํ ์
- โ ์ฌ์ฉ์ ์ ๋ณด ์ ๋ ฅ๋ฐ๊ธฐ ์์
- โญ๏ธ ์์ฝ
- โ ์ ์ํ ๊ณต์ (State Lifting)๋ฅผ ํ ๊น?
- ๐ ๊ฐ๋จํ ์์: ๋ input์ ๋๊ธฐํ
- โญ๏ธ ํต์ฌ ์ ๋ฆฌ
- โ ์ธ์ ์ํ๋ฅผ ๋์ด์ฌ๋ฆด๊น?
- โ React๋ ์์๋ณด๋ค ํฉ์ฑ์ ๊ถ์ฅ
- ๐ ์ปดํฌ๋ํธ ํฉ์ฑ์ ์ข ๋ฅ
- 1. Containment (์ปจํ ์ธ๋จผํธ: ์์ ํฌํจ)
- 2. Specialization (ํน์ํ: ์ผ๋ถ ๋ด์ฉ๋ง ๋ณ๊ฒฝ)
- โญ๏ธ ํฉ์ฑ๊ณผ ์์ ๋น๊ต
- โ ์ธ์ Context๋ฅผ ์จ์ผ ํ ๊น?
- ๐งช ๊ฐ๋จํ Context ์ฌ์ฉ ์์
- 1. Context ์์ฑํ๊ธฐ
- 2. Context ์ ๊ณตํ๊ธฐ (Provider)
- 3. Context ์ฌ์ฉํ๊ธฐ (Consumer ๋๋ Hook)
- โก ๋ ๊ฐ๋จํ๊ฒ: useContext Hook
- ๐ Context ํ๋ฆ ์์ฝ
- โ ๏ธ Context ์ฌ์ฉ ์ ์ฃผ์์
- โจ ์ธ์ Context๋ฅผ ์ฌ์ฉํ๋ฉด ์ข์๊น?
- โ CSS ๊ธฐ๋ณธ ๋ฌธ๋ฒ
- ์์:
- ๐ ์ ํ์(Selector) ์ข ๋ฅ
- 1๏ธโฃ ํ๊ทธ ์ ํ์ (Element Selector)
- 2๏ธโฃ ํด๋์ค ์ ํ์ (Class Selector)
- 3๏ธโฃ ID ์ ํ์ (ID Selector)
- 4๏ธโฃ ๊ทธ๋ฃน ์ ํ์ (Grouping Selector)
- 5๏ธโฃ ์ ์ฒด ์ ํ์ (Universal Selector)
- 6๏ธโฃ ๊ฒฐํฉ ์ ํ์ (์กฐํฉ)
- ๐ฏ ์ํ ์ ํ์ (Pseudo-class)
- โ ํ ์คํธ ๊ด๋ จ ์์ฑ ์์
- โ ๋ฐ์ค ๋ชจ๋ธ ๊ด๋ จ ์์ฑ ์์
- ๐ก ์ ๋ฆฌ
- โ 1. display
- ์์ฃผ ์ฐ์ด๋ ๊ฐ
- โ 2. visibility
- โ 3. position
- ์์:
- โ 4. width, height
- โ 5. margin, padding
- ๋ฐฉํฅ๋ณ ์์ฑ
- โ 6. Flexbox ๊ธฐ์ด
- ์์ฃผ ์ฌ์ฉํ๋ ์์ฑ
- ์์:
- โญ๏ธ ์ ๋ฆฌ
- โ ๊ธฐ๋ณธ ๊ตฌ์กฐ
- ๐ ์ฃผ์ ์ฉ์ด ์ ๋ฆฌ
- ๐งญ 1. flex-direction
- ๐ 2. justify-content
- ๐งฒ 3. align-items
- ๐ 4. flex-wrap
- ๐ง 5. align-content
- ๐ 6. ๊ฐ๋ณ ์์ดํ ์ ๋ ฌ - align-self
- ๐งช Flex ์์ฑ ์์
- ๐ก Flex ์์ดํ ์ ์ฉ ์์ฑ
- โญ๏ธ ์ ๋ฆฌ
- โจ ๊ธฐ๋ณธ ์ฌ์ฉ๋ฒ
- ๐ฏ props๋ก ์คํ์ผ ๋์ ์ ์ด
- ๐ ์คํ์ผ ํ์ฅํ๊ธฐ
- ๐ ์ ์ญ ์คํ์ผ ์ค์ - createGlobalStyle
- โญ๏ธ ์ ๋ฆฌ
๐ก ์กฐ๊ฑด๋ถ ๋ ๋๋ง (Conditional Rendering)
๋ฆฌ์กํธ์์๋ ์ํฉ์ ๋ฐ๋ผ ๋ค๋ฅธ UI๋ฅผ ๋ณด์ฌ์ฃผ๋ ๊ฒ์ โ์กฐ๊ฑด๋ถ ๋ ๋๋งโ์ด๋ผ๊ณ ํ๋ค.
๊ธฐ๋ณธ์ ์ผ๋ก๋ JavaScript์ ์กฐ๊ฑด๋ฌธ์ ํ์ฉํ์ฌ ์ปดํฌ๋ํธ ์์์ ๋ ๋๋งํ ๋ด์ฉ์ ๋์ ์ผ๋ก ๋ฐ๊ฟ ์ ์๋ค.
โ ์กฐ๊ฑด๋ถ ๋ ๋๋ง์ ์ฌ์ฉ
React์์๋ ๋ง์น if๋ฌธ์ฒ๋ผ ํน์ ์กฐ๊ฑด์ ๋ฐ๋ผ ๋ค๋ฅธ ์ปดํฌ๋ํธ๋ JSX ์์๋ฅผ ๋ ๋๋งํ ์ ์๋ค.
์๋ฅผ ๋ค์ด, ๋ก๊ทธ์ธ ์ํ์ ๋ฐ๋ผ ํ๋ฉด์ โํ์ํฉ๋๋ค!โ ๋๋ โ๋ก๊ทธ์ธ ํด์ฃผ์ธ์โ๋ฅผ ๋ณด์ฌ์ค ์ ์๋ค.
๐ ์กฐ๊ฑด๋ถ ๋ ๋๋ง ๋ฐฉ์
1. if ๋ฌธ ์ฌ์ฉ
function Greeting(props) {
const isLoggedIn = props.isLoggedIn;
if (isLoggedIn) {
return <h1>ํ์ํฉ๋๋ค!</h1>;
}
return <h1>๋ก๊ทธ์ธ ํด์ฃผ์ธ์.</h1>;
}
- ๊ฐ์ฅ ์ง๊ด์ ์ธ ๋ฐฉ์์ผ๋ก, ์กฐ๊ฑด์ ๋ฐ๋ผ ์ปดํฌ๋ํธ๋ฅผ ๋ฐํํ๋ค.
- ์ฌ๋ฌ ์กฐ๊ฑด์ด ๋ณต์กํ ๋ ์ฌ์ฉํ๋ฉด ๊ฐ๋ ์ฑ์ด ์ข๋ค.
2. ์ผํญ ์ฐ์ฐ์ ์ฌ์ฉ (Inline ์กฐ๊ฑด)
function Greeting(props) {
return (
<h1>
{props.isLoggedIn ? 'ํ์ํฉ๋๋ค!' : '๋ก๊ทธ์ธ ํด์ฃผ์ธ์.'}
</h1>
);
}
- ๊ฐ๋จํ ์กฐ๊ฑด์ผ ๊ฒฝ์ฐ ์งง๊ณ ๊น๋ํ ์ฝ๋๋ฅผ ์์ฑํ ์ ์๋ค.
- JSX ๋ด๋ถ์์ ์ง์ ์ฌ์ฉํ ์ ์๋ค๋ ์ ์ด ํน์ง
3. && ์ฐ์ฐ์ ์ฌ์ฉ
function Mailbox(props) {
const unreadMessages = props.unreadMessages;
return (
<div>
<h1>์๋
ํ์ธ์!</h1>
{unreadMessages.length > 0 && (
<h2>์ฝ์ง ์์ ๋ฉ์์ง: {unreadMessages.length}๊ฐ</h2>
)}
</div>
);
}
- ํน์ ์กฐ๊ฑด์ด true์ผ ๋๋ง JSX๋ฅผ ๋ ๋๋งํ๊ณ ์ถ์ ๋ ์ฌ์ฉํ๋ค.
unreadMessages.length > 0์ด ์ฐธ์ด๋ฉด<h2>๊ฐ ๋ ๋๋ง๋๋ค.
โ ์ฃผ์์ฌํญ: false, null, undefined๋ ๋ ๋๋ง๋์ง ์์
return <div>{false}</div>; // ํ๋ฉด์ ์๋ฌด๊ฒ๋ ๋ ๋๋ง๋์ง ์์
- JSX์์๋
false,null,undefined,true๋ ๋ฌด์๋๊ณ ํ๋ฉด์ ํ์๋์ง ์๋๋ค..
โจ ์์ : ๋ก๊ทธ์ธ ๋ฒํผ ์ ํ
function LoginButton(props) {
return <button onClick={props.onClick}>๋ก๊ทธ์ธ</button>;
}
function LogoutButton(props) {
return <button onClick={props.onClick}>๋ก๊ทธ์์</button>;
}
function LoginControl() {
const [isLoggedIn, setIsLoggedIn] = useState(false);
const handleClick = () => {
setIsLoggedIn(!isLoggedIn);
};
return (
<div>
{isLoggedIn ? (
<LogoutButton onClick={handleClick} />
) : (
<LoginButton onClick={handleClick} />
)}
</div>
);
}
- ๋ฒํผ์ ํด๋ฆญํ ๋๋ง๋ค **์ํ(State)**๊ฐ ๋ฐ๋๊ณ ,
- ๊ทธ์ ๋ฐ๋ผ ๋ค๋ฅธ ์ปดํฌ๋ํธ๊ฐ ์กฐ๊ฑด๋ถ๋ก ๋ ๋๋ง๋๋ค.
โญ๏ธ ์์ฝ
| ๋ฐฉ์ | ์ค๋ช | ํน์ง |
|---|---|---|
if ๋ฌธ |
JSX ๋ฐ๊นฅ์์ ์กฐ๊ฑด์ ๋ถ๊ธฐ | ๋ณต์กํ ์กฐ๊ฑด์ ์ ํฉ |
์ผํญ ์ฐ์ฐ์ |
JSX ์์์ ์กฐ๊ฑด ๋ถ๊ธฐ | ๊ฐ๋จํ ์กฐ๊ฑด ์ฒ๋ฆฌ |
&& ์ฐ์ฐ์ |
true์ผ ๋๋ง ๋ ๋๋ง | ์กฐ๊ฑด๋ถ ์ถ๋ ฅ์ ๊ฐํธ |
โ๏ธ ์กฐ๊ฑด๋ถ ๋ ๋๋ง์ ์ฌ์ฉ์ ๊ฒฝํ์ ํฅ์์ํค๊ธฐ ์ํ ํ์ ๊ธฐ๋ฅ
๐ก ๋ฆฌ์คํธ์ Key
๋ฆฌ์กํธ์์๋ ์ฌ๋ฌ ๊ฐ์ ๋ฐ์ดํฐ๋ฅผ ๋ฐ๋ณตํด์ ํ๋ฉด์ ํ์ํ ๋, ๋ฆฌ์คํธ ๋ ๋๋ง ๊ธฐ๋ฅ์ ์ฌ์ฉ
์ด๋ ๊ฐ ํญ๋ชฉ์ ๊ตฌ๋ถํ๊ธฐ ์ํด ๋ฐ๋์ ๊ณ ์ ํ Key๊ฐ ํ์
โ ๋ฆฌ์คํธ ๋ ๋๋ง์ด๋?
JavaScript์ map() ํจ์๋ฅผ ์ฌ์ฉํ์ฌ ๋ฐฐ์ด ์์ ๋ฐ์ดํฐ๋ฅผ ๋ฐ๋ณต์ ์ผ๋ก ๋ ๋๋งํ ์ ์๋ค.
๐ ์์ : ๋ฐฐ์ด์ ํ๋ฉด์ ์ถ๋ ฅํ๊ธฐ
const numbers = [1, 2, 3, 4, 5];
const listItems = numbers.map((number) =>
<li>{number}</li>
);
return <ul>{listItems}</ul>;
map()์ ์ฌ์ฉํ์ฌ ๋ฐฐ์ด ์์๋ค์ li๋ก ๋ณํํ ๋ค, JSX๋ก ์ถ๋ ฅ
๐ Key๋?
๋ฆฌ์คํธ์ ๊ฐ ํญ๋ชฉ์ ๊ตฌ๋ถํ๊ธฐ ์ํ ๊ณ ์ ํ ๊ฐ
๋ฆฌ์กํธ๋ ์ด๋ค ํญ๋ชฉ์ด ๋ณ๊ฒฝ, ์ถ๊ฐ, ์ญ์ ๋์๋์ง ์๋ณํ๊ธฐ ์ํด Key๋ฅผ ์ฌ์ฉํ๋ค.
const numbers = [1, 2, 3, 4, 5];
const listItems = numbers.map((number) =>
<li key={number}>{number}</li>
);
- ์ฌ๊ธฐ์
key={number}๋ ๊ฐ ํญ๋ชฉ์ ๊ณ ์ ํ๊ฒ ์๋ณํ ์ ์๋ ๊ฐ - Key๊ฐ ์๊ฑฐ๋ ์ค๋ณต๋๋ฉด ๊ฒฝ๊ณ ๋ฉ์์ง๊ฐ ๋จ๊ณ ์ฑ๋ฅ์ด ์ ํ๋ ์ ์๋ค.
โ key์ index๋ฅผ ์ฌ์ฉํด๋ ๋ ๊น?
const listItems = items.map((item, index) =>
<li key={index}>{item}</li>
);
- key๋ก
index๋ฅผ ์ฌ์ฉํ๋ ๊ฑด ๊ถ์ฅ๋์ง ์๋๋ค. โ - ์ด์ : ๋ฆฌ์คํธ์ ์์๊ฐ ๋ฐ๋๊ฑฐ๋ ํญ๋ชฉ์ด ์ถ๊ฐ/์ญ์ ๋๋ฉด index ๊ฐ์ด ๋ฐ๋์ด ์๋ชป๋ ๋๊ธฐํ๊ฐ ๋ฐ์ํ ์ ์์
๊ฐ๋ฅํ ๊ฒฝ์ฐ์ ๊ณ ์ ID๊ฐ์ key๋ก ์ฌ์ฉํ๋ ๊ฒ์ด ์ข๋ค.
โญ๏ธ ์์ฝ
| ๊ฐ๋ | ์ค๋ช |
|---|---|
| ๋ฆฌ์คํธ ๋ ๋๋ง | map() ํจ์๋ฅผ ์ด์ฉํ์ฌ ๋ฐ๋ณต ๋ ๋๋ง |
| key | ๊ฐ ํญ๋ชฉ์ ๊ณ ์ ํ๊ฒ ์๋ณํ๊ธฐ ์ํ ๊ฐ |
| ์ข์ key ๊ฐ | ๊ณ ์ ํ ID (index๋ ์ง์) |
๐ก Form๊ณผ Controlled Component
์ฌ์ฉ์๋ก๋ถํฐ ์ ๋ ฅ์ ๋ฐ์ ๋ ์ฌ์ฉํ๋ HTML ์์์ธ Form,
๊ทธ๋ฆฌ๊ณ ์ ๋ ฅ๊ฐ์ ๋ฆฌ์กํธ์์ ์ง์ ์ ์ดํ๋ ๋ฐฉ์์ Controlled Component๋ผ๊ณ ํ๋ค.
โ ์ Controlled Component๋ฅผ ์ฌ์ฉํ ๊น?
๊ธฐ์กด HTML์์๋ <input>, <textarea>, <select> ๋ฑ form ์์๋ค์ด DOM์ด ์ง์ ๊ด๋ฆฌํ๋ค.
ํ์ง๋ง ๋ฆฌ์กํธ์์๋ ์ํ(state)๋ฅผ ํตํด ์ ๋ ฅ๊ฐ์ ์ ์ด(์ ์ด๋ ์ปดํฌ๋ํธ) ํ๋ฉด์
์ ๋ ฅ๋ ๊ฐ์ ์ค์๊ฐ์ผ๋ก ์ถ์ ํ๊ณ , ์กฐ๊ฑด์ ๋ฐ๋ผ ๋์์ ์ ์ฐํ๊ฒ ๋ณ๊ฒฝํ ์ ์๋ค.
โ๏ธ Controlled Component ๊ธฐ๋ณธ ์์
import { useState } from "react";
function NameForm() {
const [name, setName] = useState("");
const handleChange = (e) => {
setName(e.target.value); // ์
๋ ฅ๊ฐ์ ์ํ์ ์ ์ฅ
};
const handleSubmit = (e) => {
e.preventDefault(); // ๊ธฐ๋ณธ ๋์(ํ์ด์ง ์๋ก๊ณ ์นจ) ๋ง๊ธฐ
alert(`์
๋ ฅํ ์ด๋ฆ: ${name}`);
};
return (
<form onSubmit={handleSubmit}>
<input type="text" value={name} onChange={handleChange} />
<button type="submit">์ ์ถ</button>
</form>
);
}
value={name}: input์ ๊ฐ์ ์ํ์ ์ฐ๊ฒฐonChange={handleChange}: ์ ๋ ฅํ ๋๋ง๋ค ์ํ ๊ฐฑ์useState๋ฅผ ํตํด ์ ๋ ฅ๊ฐ์ ์ ์ด (Controlled)
โ ๋ค์ํ Form ์์๋ค ์ ์ดํ๊ธฐ
๐ textarea ์ ์ด
<textarea value={message} onChange={(e) => setMessage(e.target.value)} />
๐ select ์ ์ด
<select value={selectedOption} onChange={(e) => setSelectedOption(e.target.value)}>
<option value="apple">Apple</option>
<option value="banana">Banana</option>
</select>
- select์
value๋ ์ํ์ ์ฐ๊ฒฐ - ๋ค์ํ ์ ๋ ฅ ์์๋ฅผ ๋์ผํ ๋ฐฉ์์ผ๋ก ์ ์ด ๊ฐ๋ฅ
โ ์ฃผ์ํ ์
- input์
value๋ฅผ ์ง์ ํ๋๋ฐonChange๋ฅผ ๋น ๋จ๋ฆฌ๋ฉด ์ ๋ ฅ ๋ถ๊ฐ๋ฅํ ํ๋๊ฐ ๋๋ค. - ํญ์
value์onChange๋ฅผ ํจ๊ป ์ฌ์ฉํด์ผ ํฉ๋๋ค.
โ ์ฌ์ฉ์ ์ ๋ณด ์ ๋ ฅ๋ฐ๊ธฐ ์์
function UserForm() {
const [userInfo, setUserInfo] = useState({ name: "", email: "" });
const handleChange = (e) => {
const { name, value } = e.target;
setUserInfo((prev) => ({
...prev,
[name]: value,
}));
};
return (
<form>
<input name="name" value={userInfo.name} onChange={handleChange} />
<input name="email" value={userInfo.email} onChange={handleChange} />
</form>
);
}
- ์ฌ๋ฌ ๊ฐ์ input์ ๊ฐ์ฒด ํํ๋ก ์ํ ๊ด๋ฆฌ
name์์ฑ์ ํตํด ์ด๋ค ํ๋์ธ์ง ๊ตฌ๋ถ
โญ๏ธ ์์ฝ
| ๊ฐ๋ | ์ค๋ช |
|---|---|
| Controlled Component | ๋ฆฌ์กํธ ์ํ๊ฐ form ์์์ ๊ฐ์ ์ ์ด |
| value | ์ํ ๊ฐ์ input ๋ฑ์ ์ฐ๊ฒฐ |
| onChange | ์ ๋ ฅ ๋ณํ ์ ์ํ ์ ๋ฐ์ดํธ |
| ์ฅ์ | ์ ๋ ฅ๊ฐ ์ถ์ , ์กฐ๊ฑด ์ ์ด, ์ค์๊ฐ ๊ฒ์ฆ ๊ฐ๋ฅ |
๐ก ์ํ ๊ณต์ (State Lifting)
์ํ ๊ณต์ ๋, ์ฌ๋ฌ ํ์ ์ปดํฌ๋ํธ๋ค์ด ๋์ผํ ์ํ๋ฅผ ์ฌ์ฉํ ๋,
๊ทธ ์ํ๋ฅผ ๊ณตํต์ ์์ ์ปดํฌ๋ํธ๋ก ์ฌ๋ ค์(lift up) ๊ด๋ฆฌํ๋ ํจํด
โ ์ ์ํ ๊ณต์ (State Lifting)๋ฅผ ํ ๊น?
React์์ ์ปดํฌ๋ํธ๋ ๋ ๋ฆฝ์ ์ธ ์ํ(state) ๋ฅผ ๊ฐ์ง๋ค.
ํ์ง๋ง ๋๋ก๋ ์ฌ๋ฌ ์ปดํฌ๋ํธ๊ฐ ๋์ผํ ๋ฐ์ดํฐ๋ฅผ ๊ณต์ ํด์ผ ํ ๋๊ฐ ์๋ค.
์ด๋ ์ํ๋ฅผ ํ์ ์ปดํฌ๋ํธ ๊ฐ๊ฐ์ ๋ง๋ค๋ฉด โ ๋ฐ์ดํฐ ๋ถ์ผ์น ๋ฐ์
โ ํด๊ฒฐ ๋ฐฉ๋ฒ: ์ํ๋ฅผ ๊ณตํต ๋ถ๋ชจ ์ปดํฌ๋ํธ๋ก ๋์ด์ฌ๋ฆผ
๐ ๊ฐ๋จํ ์์: ๋ input์ ๋๊ธฐํ
function TemperatureInput({ temperature, onTemperatureChange }) {
return (
<fieldset>
<inputvalue={temperature}
onChange={(e) => onTemperatureChange(e.target.value)}
/>
</fieldset>
);
}
function Calculator() {
const [temperature, setTemperature] = useState("");
return (
<div>
<TemperatureInputtemperature={temperature}
onTemperatureChange={setTemperature}
/>
<TemperatureInputtemperature={temperature}
onTemperatureChange={setTemperature}
/>
</div>
);
}
Calculator์ปดํฌ๋ํธ๊ฐ ์ํ๋ฅผ ๊ฐ์ง๊ณ ์๊ณ ,TemperatureInput์ ์ํ๋ฅผ props๋ก ๋ฐ์์ ํ์ & ์์ ํจ- ์ด๋ ๊ฒ ์ํ๋ฅผ ์์ ์ปดํฌ๋ํธ์ ์ฌ๋ฆฌ๋ ๊ฒ์ State Lifting์ด๋ผ๊ณ ํจ
โญ๏ธ ํต์ฌ ์ ๋ฆฌ
| ๊ฐ๋ | ์ค๋ช |
|---|---|
| ์ํ ๊ณต์ | ์ฌ๋ฌ ์ปดํฌ๋ํธ๊ฐ ๋์ผํ ์ํ๋ฅผ ์ฌ์ฉ |
| Lifting State Up | ๊ณตํต ๋ถ๋ชจ ์ปดํฌ๋ํธ๋ก ์ํ๋ฅผ ์ฌ๋ ค ๊ด๋ฆฌ |
| ์ฅ์ | ๋ฐ์ดํฐ ๋๊ธฐํ, ํ๋ฆ์ด ๋ช ํํด์ง |
| ๋จ์ | ์ปดํฌ๋ํธ ๊ฐ์ ๊ฒฐํฉ๋๊ฐ ๋ค์ ์ฌ๋ผ๊ฐ |
โ ์ธ์ ์ํ๋ฅผ ๋์ด์ฌ๋ฆด๊น?
- 2๊ฐ ์ด์์ ํ์ ์ปดํฌ๋ํธ๊ฐ ๊ฐ์ ๋ฐ์ดํฐ๋ฅผ ํ์๋ก ํ ๋
- ํ์ ์ปดํฌ๋ํธ๋ผ๋ฆฌ ์ํ๋ฅผ ๊ณต์ ํด์ผ ํ ๋
- ์: ํํฐ๋ง๋ ๋ฆฌ์คํธ๋ฅผ ๋ณด์ฌ์ฃผ๋ ์ปดํฌ๋ํธ์ ๊ฒ์์ด ์ ๋ ฅ์ฐฝ
SearchInput: ๊ฒ์์ด ์ ๋ ฅList: ํํฐ๋ง๋ ๊ฒฐ๊ณผ ํ์- ๊ณตํต๋ ์ํ
filterText๋ ์์ ์ปดํฌ๋ํธFilterableList์์ ๊ด๋ฆฌ
๐ก ์ปดํฌ๋ํธ ํฉ์ฑ๊ณผ ์์
React์์๋ ํฉ์ฑ(Composition) ์ ํตํด ์ปดํฌ๋ํธ๋ฅผ ์กฐํฉํ๊ณ ,
์์(Inheritance) ๋ณด๋ค๋ ํฉ์ฑ์ ์ฐ์ ์ ์ผ๋ก ์ฌ์ฉ
โ React๋ ์์๋ณด๋ค ํฉ์ฑ์ ๊ถ์ฅ
-
ํด๋์ค ๊ธฐ๋ฐ ๊ฐ์ฒด์งํฅ ์ธ์ด์์๋ ์์์ ๋ง์ด ์ฌ์ฉํ์ง๋ง,
React์์๋ ๋๋ถ๋ถ์ ๋ฌธ์ ๋ฅผ ์ปดํฌ๋ํธ ํฉ์ฑ์ผ๋ก ํด๊ฒฐํ ์ ์๋ค.
-
ํฉ์ฑ์ ๋ ์ ์ฐํ๊ณ ์ฌ์ฌ์ฉ์ฑ ๋์ ๊ตฌ์กฐ๋ฅผ ๋ง๋ค ์ ์๋ค.
๐ ์ปดํฌ๋ํธ ํฉ์ฑ์ ์ข ๋ฅ
React์์๋ ์ปดํฌ๋ํธ๋ฅผ ์กฐํฉํ๋ ๋ฐฉ๋ฒ์ผ๋ก ์๋ ๋ ๊ฐ์ง ํฉ์ฑ ํจํด์ ์ฃผ๋ก ์ฌ์ฉํ๋ค.
1. Containment (์ปจํ ์ธ๋จผํธ: ์์ ํฌํจ)
์์ ์๋ฆฌ๋จผํธ๋ฅผ props.children์ผ๋ก ๋ฐ์์ ๋ ๋๋งํ๋ ๋ฐฉ์
function Card({ children }) {
return <div className="card">{children}</div>;
}
<Card>
<h2>๊ณต์ง์ฌํญ</h2>
<p>์ด๋ฒ ์ฃผ ๊ธ์์ผ์ ํด๊ฐ์
๋๋ค.</p>
</Card>
โ props.children์ ํ์ฉํ๋ฉด,
๋ถ๋ชจ ์ปดํฌ๋ํธ๊ฐ ์์์ผ๋ก ์ด๋ค ์์๋ ์์ ๋กญ๊ฒ ๋๊ธธ ์ ์๋ค.
2. Specialization (ํน์ํ: ์ผ๋ถ ๋ด์ฉ๋ง ๋ณ๊ฒฝ)
์ผ๋ฐ์ ์ธ ์ปดํฌ๋ํธ๋ฅผ ํน์ ์ฉ๋์ ๋ง๊ฒ ์ฌ์ฌ์ฉํ๋ ๋ฐฉ์
function Dialog({ title, message }) {
return (
<div className="dialog">
<h1>{title}</h1>
<p>{message}</p>
</div>
);
}
function WelcomeDialog() {
return <Dialog title="ํ์ํฉ๋๋ค!" message="์ ํฌ ์ฌ์ดํธ์ ์ค์ ๊ฑธ ํ์ํด์." />;
}
โ ์ผ๋ฐ์ ์ธ ๊ตฌ์กฐ๋ ์ ์งํ๋ฉด์,
๋ด์ฉ๋ง ๋ฐ๊พธ๊ณ ์ถ์ ๋ ์ ํฉํ ๋ฐฉ์
โญ๏ธ ํฉ์ฑ๊ณผ ์์ ๋น๊ต
| ํญ๋ชฉ | ํฉ์ฑ(Composition) | ์์(Inheritance) |
|---|---|---|
| ์ฌ์ฉ์ฑ | React์์ ๊ถ์ฅ โ | ๊ฑฐ์ ์ฌ์ฉ ์ ํจ โ |
| ์ฅ์ | ์ ์ฐํ๊ณ ์กฐ๋ฆฝ ๊ฐ๋ฅ | ์ฝ๋ ๊ฒฐํฉ๋ ๋์ |
| ์์ | children, props | extends ํด๋์ค ์์ ๋ฑ |
๐ก Context API๋?
Context๋ ์ปดํฌ๋ํธ ํธ๋ฆฌ ์ ์ฒด์ ๋ฐ์ดํฐ(์ํ)๋ฅผ ๊ณต์ ํ ์ ์๊ฒ ํด์ฃผ๋ ๋ฆฌ์กํธ ๊ธฐ๋ฅ
React๋ ๊ธฐ๋ณธ์ ์ผ๋ก ๋จ๋ฐฉํฅ ๋ฐ์ดํฐ ํ๋ฆ์ ์ฌ์ฉํ๋ค.
์ฆ, ๋ถ๋ชจ โ ์์์ผ๋ก props๋ฅผ ํตํด ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌ
ํ์ง๋ง, ์ปดํฌ๋ํธ ๊น์ด๊ฐ ๊น์ด์ง๋ฉด
๋งค๋ฒ props๋ก ์ ๋ฌํ๋ ๊ฒ์ด ๋งค์ฐ ๋ฒ๊ฑฐ๋กญ๊ณ ๋นํจ์จ์ ์ด๋ค.
โ ์ด๋ด ๋ ๋ฑ์ฅํ๋ ๊ฒ์ด ๋ฐ๋ก Context API
โ ์ธ์ Context๋ฅผ ์จ์ผ ํ ๊น?
์ฌ๋ฌ ์ปดํฌ๋ํธ์์ ๋์ผํ ๋ฐ์ดํฐ๋ฅผ ํ์๋ก ํ ๋
์๋ฅผ ๋ค๋ฉด ์ด๋ฐ ๋ฐ์ดํฐ๋ค:
- ์ฌ์ฉ์ ๋ก๊ทธ์ธ ์ ๋ณด (user)
- ํ์ฌ UI ํ ๋ง (dark / light)
- ์ ํ๋ ์ธ์ด (locale)
- ์ฌ์ดํธ ์ค์ ๊ฐ ๋ฑโฆ
๐งช ๊ฐ๋จํ Context ์ฌ์ฉ ์์
1. Context ์์ฑํ๊ธฐ
import React from "react";
// ๊ธฐ๋ณธ๊ฐ์ผ๋ก "light"๋ฅผ ์ค์
const ThemeContext = React.createContext("light");
2. Context ์ ๊ณตํ๊ธฐ (Provider)
function App() {
return (
<ThemeContext.Provider value="dark">
<Toolbar />
</ThemeContext.Provider>
);
}
value๋ก ํ์ ์ปดํฌ๋ํธ์๊ฒ ๊ณต์ ํ ๊ฐ์ ๋๊ฒจ์ค๋ค.
3. Context ์ฌ์ฉํ๊ธฐ (Consumer ๋๋ Hook)
function Toolbar() {
return (
<div>
<ThemedButton />
</div>
);
}
function ThemedButton() {
return (
<ThemeContext.Consumer>
{(theme) => <button className={theme}>๋ฒํผ</button>}
</ThemeContext.Consumer>
);
}
โก ๋ ๊ฐ๋จํ๊ฒ: useContext Hook
ํจ์ํ ์ปดํฌ๋ํธ์์๋ useContext()๋ฅผ ์ฌ์ฉํ๋ฉด ํจ์ฌ ๊ฐ๋จํด์!
import { useContext } from "react";
function ThemedButton() {
const theme = useContext(ThemeContext);
return <button className={theme}>๋ฒํผ</button>;
}
๐ Context ํ๋ฆ ์์ฝ
React.createContext()๋ก ์์ฑProvider๋ก ๋ฐ์ดํฐ ์ ๊ณต- ํ์ ์ปดํฌ๋ํธ์์
useContext()๋๋Consumer๋ก ๋ฐ์ดํฐ ์ฌ์ฉ
โ ๏ธ Context ์ฌ์ฉ ์ ์ฃผ์์
| ์ฃผ์ํ ์ | ์ค๋ช |
|---|---|
| ๋ฆฌ๋ ๋๋ง ์ฃผ์ | Context์ value๊ฐ ๋ณ๊ฒฝ๋๋ฉด ํ์ ์ปดํฌ๋ํธ ์ ๋ถ ๋ฆฌ๋ ๋๋ง |
| ๊ณผ๋ํ ์ฌ์ฉ โ | ๋ชจ๋ ์ํ๋ฅผ Context๋ก ๊ด๋ฆฌํ๋ฉด ์คํ๋ ค ๋ณต์กํด์ง |
| props๋ก ์ถฉ๋ถํ ๊ฒฝ์ฐ | ๋จ์ํ ๋ฐ์ดํฐ ์ ๋ฌ์ด๋ฉด props๊ฐ ๋ ํจ์จ์ ์ผ ์ ์์ |
โจ ์ธ์ Context๋ฅผ ์ฌ์ฉํ๋ฉด ์ข์๊น?
- ๋ก๊ทธ์ธํ ์ฌ์ฉ์ ์ ๋ณด (user)
- ํ ๋ง ์ ๋ณด (๋คํฌ๋ชจ๋, ๋ผ์ดํธ๋ชจ๋)
- ์ธ์ด ์ค์
- ์ฅ๋ฐ๊ตฌ๋ ์ํ (e-commerce)
๐จ CSS ๊ธฐ๋ณธ ๋ฌธ๋ฒ๊ณผ ์ ๋ ํฐ
CSS๋ ์น์ฌ์ดํธ๋ฅผ ๊พธ๋ฏธ๋ ์ธ์ด
HTML๋ก ๊ตฌ์กฐ๋ฅผ ๋ง๋ค๊ณ , CSS๋ก ์๊น, ํฌ๊ธฐ, ๋ฐฐ์น, ์ ๋๋ฉ์ด์ ๋ฑ์ ์ง์ ํ ์ ์๋ค.
โ CSS ๊ธฐ๋ณธ ๋ฌธ๋ฒ
์ ํ์ {
์์ฑ: ๊ฐ;
}
์์:
h1 {
color: blue;
font-size: 24px;
}
- ์ ํ์(selector): ์ด๋ค HTML ์์์ ์คํ์ผ์ ์ ์ฉํ ์ง ์ ํ
- ์์ฑ(property): ๋ณ๊ฒฝํ๊ณ ์ถ์ ์คํ์ผ ํญ๋ชฉ (ex. ์์, ๊ธ์จ ํฌ๊ธฐ ๋ฑ)
- ๊ฐ(value): ์์ฑ์ ์ ์ฉํ ๊ตฌ์ฒด์ ์ธ ๊ฐ
๐ ์ ํ์(Selector) ์ข ๋ฅ
1๏ธโฃ ํ๊ทธ ์ ํ์ (Element Selector)
h1 {
color: green;
}
โ ๋ชจ๋ <h1> ํ๊ทธ์ ์ ์ฉ
2๏ธโฃ ํด๋์ค ์ ํ์ (Class Selector)
.title {
font-weight: bold;
}
โ class ์์ฑ์ด "title"์ธ ์์์ ์ ์ฉ
์ฌ์ฉ ์ HTML์ class ์ด๋ฆ์ ๋ถ์ฌํด์ผ ํจ
<p class="title">์ค์ํ ๋ฌธ์ฅ</p>
3๏ธโฃ ID ์ ํ์ (ID Selector)
#main {
background-color: yellow;
}
โ id ์์ฑ์ด "main"์ธ ์์์ ์ ์ฉ
์ฃผ์: ID๋ ํ ํ์ด์ง์ ํ๋๋ง
<div id="main">๋ด์ฉ</div>
4๏ธโฃ ๊ทธ๋ฃน ์ ํ์ (Grouping Selector)
h1, h2, p {
margin: 0;
}
โ ์ฌ๋ฌ ํ๊ทธ์ ๊ฐ์ ์คํ์ผ์ ํ ๋ฒ์ ์ ์ฉ
5๏ธโฃ ์ ์ฒด ์ ํ์ (Universal Selector)
* {
box-sizing: border-box;
}
โ ๋ชจ๋ ์์์ ์ ์ฉ
์ด๊ธฐํ๋ ๊ณตํต ์คํ์ผ ์ค์ ์ ์ ์ฉ
6๏ธโฃ ๊ฒฐํฉ ์ ํ์ (์กฐํฉ)
div.title {
color: red;
}
โ div ํ๊ทธ ์ค์ class๊ฐ "title"์ธ ์์์๋ง ์ ์ฉ
#main .title {
font-size: 18px;
}
โ id๊ฐ "main"์ธ ์์ ๋ด๋ถ์ class "title" ์์์ ์ ์ฉ
๐ฏ ์ํ ์ ํ์ (Pseudo-class)
์๋ฆฌ๋จผํธ์ ํน์ ์ํ์ ๋ฐ๋ผ ์คํ์ผ์ ์ ์ฉํ ์ ์๋ค.
| ์ ํ์ | ์ค๋ช |
|---|---|
:hover |
๋ง์ฐ์ค ์ค๋ฒ ์ |
:active |
ํด๋ฆญ ์ค์ผ ๋ |
:focus |
ํฌ์ปค์ค(์ ๋ ฅ์ฐฝ ์ ํ) ์ํ |
:first-child |
๋ถ๋ชจ์ ์ฒซ ๋ฒ์งธ ์์ ์์ |
:last-child |
๋ถ๋ชจ์ ๋ง์ง๋ง ์์ ์์ |
button:hover {
background-color: skyblue;
}
โ ํ ์คํธ ๊ด๋ จ ์์ฑ ์์
p {
font-size: 16px;
color: #333;
text-align: center;
}
โ ๋ฐ์ค ๋ชจ๋ธ ๊ด๋ จ ์์ฑ ์์
.box {
width: 100px;
height: 100px;
padding: 10px;
border: 1px solid black;
margin: 20px;
}
๐ก ์ ๋ฆฌ
| ์์ | ์ค๋ช |
|---|---|
| ์ ํ์ | ์คํ์ผ ์ ์ฉ ๋์์ ์ง์ |
| ์์ฑ | ์ด๋ค ์คํ์ผ์ ์ค์ง ์ง์ |
| ๊ฐ | ๊ตฌ์ฒด์ ์ธ ์คํ์ผ ๊ฐ ์ค์ |
๐ CSS ๋ ์ด์์ ๊ด๋ จ ์์ฑ ์ ๋ฆฌ
CSS ๋ ์ด์์ ์์ฑ์ ์น ํ์ด์ง์ ๊ตฌ์กฐ์ ์์๋ค์ ๋ฐฐ์น ์์น๋ฅผ ์ค์ ํ๋ ๋ฐ ์ฌ์ฉ๋๋ค.
ํ๋์ ๋ณด๊ธฐ ์ฝ๊ณ , ๊ตฌ์กฐ๊ฐ ๊น๋ํ ์น์ฌ์ดํธ๋ฅผ ๋ง๋ค๊ธฐ ์ํ ํต์ฌ ๋๊ตฌ
โ
1. display
์์์ ํ์ ๋ฐฉ์์ ์ง์ ํ๋ ์์ฑ
์์ฃผ ์ฐ์ด๋ ๊ฐ
| ๊ฐ | ์ค๋ช |
|---|---|
block |
๋ธ๋ก ์์. ํ ์ค ์ ์ฒด๋ฅผ ์ฐจ์งํจ (div, p, h1 ๋ฑ ๊ธฐ๋ณธ๊ฐ) |
inline |
์ธ๋ผ์ธ ์์. ์ฝํ
์ธ ํฌ๊ธฐ๋งํผ๋ง ๊ณต๊ฐ ์ฐจ์ง (span, a ๋ฑ ๊ธฐ๋ณธ๊ฐ) |
none |
์์๋ฅผ ์จ๊น (ํ๋ฉด๊ณผ DOM์์ ์ฌ๋ผ์ง) |
flex |
Flexbox ๋ ์ด์์ ์ปจํ ์ด๋๋ก ์ค์ |
inline-block |
์ธ๋ผ์ธ์ฒ๋ผ ๋ฐฐ์น๋์ง๋ง ๋ธ๋ก์ฒ๋ผ width, height ์กฐ์ ๊ฐ๋ฅ |
.container {
display: flex;
}
โ
2. visibility
์์๋ฅผ ์จ๊ธธ์ง ๋ง์ง ๊ฒฐ์ ํ์ง๋ง, ๊ณต๊ฐ์ ์ ์ง๋จ
| ๊ฐ | ์ค๋ช |
|---|---|
visible |
๊ธฐ๋ณธ๊ฐ. ๋ณด์ |
hidden |
๋ณด์ด์ง ์์. ํ์ง๋ง ํด๋น ์์ญ์ ์ฐจ์ง |
.box {
visibility: hidden;
}
โ
3. position
์์๋ฅผ ์ด๋ค ๊ธฐ์ค์ผ๋ก ์์น์ํฌ์ง ์ค์ ํ๋ ์์ฑ
| ๊ฐ | ์ค๋ช |
|---|---|
static |
๊ธฐ๋ณธ๊ฐ. ๋ฌธ์ ํ๋ฆ์ ๋ฐ๋ฆ |
relative |
ํ์ฌ ์์น ๊ธฐ์ค์ผ๋ก ์ด๋ ๊ฐ๋ฅ |
absolute |
๊ฐ์ฅ ๊ฐ๊น์ด position ์ง์ ๋ ์กฐ์ ๊ธฐ์ค์ผ๋ก ์์น |
fixed |
๋ธ๋ผ์ฐ์ ์ฐฝ ๊ธฐ์ค์ผ๋ก ๊ณ ์ |
sticky |
์คํฌ๋กค ์์น์ ๋ฐ๋ผ ๊ณ ์ /ํด์ ์ ํ |
์์:
.box {
position: absolute;
top: 50px;
left: 100px;
}
โ
4. width, height
์์์ ํฌ๊ธฐ๋ฅผ ์ค์ ํ๋ ์์ฑ
.box {
width: 300px;
height: 150px;
}
auto: ์ฝํ ์ธ ์ ๋ฐ๋ผ ์๋ ์กฐ์ %: ๋ถ๋ชจ ์์์ ํฌ๊ธฐ์ ๋ํ ๋ฐฑ๋ถ์จmin-width,max-width: ์ต์/์ต๋ ํฌ๊ธฐ ์ ํ
โ
5. margin, padding
์์ ๋ฐ ์ฌ๋ฐฑ(margin) ๊ณผ ์์ชฝ ์ฌ๋ฐฑ(padding)
.box {
margin: 20px;
padding: 10px;
}
๋ฐฉํฅ๋ณ ์์ฑ
| ์์ฑ | ์ค๋ช |
|---|---|
margin-top, padding-top |
์์ชฝ ์ฌ๋ฐฑ |
margin-right, padding-right |
์ค๋ฅธ์ชฝ ์ฌ๋ฐฑ |
margin-bottom, padding-bottom |
์๋์ชฝ ์ฌ๋ฐฑ |
margin-left, padding-left |
์ผ์ชฝ ์ฌ๋ฐฑ |
โ 6. Flexbox ๊ธฐ์ด
Flexbox(ํ๋ ์ค ๋ฐ์ค) ๋ ๋ณต์กํ ๋ ์ด์์์ ๊ฐ๋จํ๊ฒ ๋ง๋๋ CSS3์ ํต์ฌ ๊ธฐ๋ฅ
.container {
display: flex;
}
์์ฃผ ์ฌ์ฉํ๋ ์์ฑ
| ์์ฑ | ์ค๋ช |
|---|---|
flex-direction |
์์ดํ
์ ๋ ฌ ๋ฐฉํฅ (row, column, row-reverse, column-reverse) |
justify-content |
์ฃผ ์ถ(Main axis) ์ ๋ ฌ (start, center, space-between, โฆ) |
align-items |
๊ต์ฐจ ์ถ(Cross axis) ์ ๋ ฌ (start, center, stretch, โฆ) |
์์:
.container {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
}
โญ๏ธ ์ ๋ฆฌ
display: ์์์ ๊ธฐ๋ณธ ํ์ ์ ํ ๊ฒฐ์ position: ํ๋ฉด์์ ์์์ ์ ํํ ์์น ์กฐ์ margin,padding: ์ฌ๋ฐฑ ์กฐ์ flex: ๋ค์ํ ๋ ์ด์์์ ์ฝ๊ฒ ๊ตฌ์ฑwidth,height: ํฌ๊ธฐ ์ค์
๐ฆ Flexbox๋?
Flexbox(Flexible Box Layout) ๋ CSS์์ 1์ฐจ์ ๋ ์ด์์์ ์ฝ๊ฒ ๊ตฌ์ฑํ๊ธฐ ์ํ ๋๊ตฌ
- ๋ณต์กํ ๋ ์ด์์์ ๋จ์ํ ์ฝ๋๋ก ๊ตฌํ ๊ฐ๋ฅ
- ์์๋ค์ ํ(row) ๋๋ ์ด(column) ๋ฐฉํฅ์ผ๋ก ์ ๋ ฌํ๊ธฐ์ ์ ํฉ
โ ๊ธฐ๋ณธ ๊ตฌ์กฐ
Flexbox๋ฅผ ์ฌ์ฉํ๋ ค๋ฉด, ๋จผ์ ๋ถ๋ชจ ์์์ display: flex ๋ฅผ ์ง์ ํด์ผ ํ๋ค.
.container {
display: flex;
}
์ด๋ ๊ฒ ํ๋ฉด .container๋ Flex Container, ๋ด๋ถ ์์๋ค์ Flex Item์ด ๋๋ค.
๐ ์ฃผ์ ์ฉ์ด ์ ๋ฆฌ
| ์ฉ์ด | ์ค๋ช |
|---|---|
| Main Axis | ์ฃผ ์ถ (๊ธฐ๋ณธ์ ์ํ) |
| Cross Axis | ๊ต์ฐจ ์ถ (๊ธฐ๋ณธ์ ์์ง) |
| Flex Container | display: flex๊ฐ ์ค์ ๋ ๋ถ๋ชจ ์์ |
| Flex Item | ์ปจํ ์ด๋ ์์ ์๋ ์์ ์์๋ค |
๐งญ 1. flex-direction
์์ดํ ์ ๋ฐฐ์น ๋ฐฉํฅ์ ์ง์ ํ๋ค.
| ๊ฐ | ์ค๋ช |
|---|---|
row |
โ ์ํ (๊ธฐ๋ณธ๊ฐ) |
row-reverse |
โ ์ํ ์ญ์ |
column |
โ ์์ง |
column-reverse |
โ ์์ง ์ญ์ |
.container {
display: flex;
flex-direction: row; /* ๋๋ column */
}
๐ 2. justify-content
Main Axis(์ฃผ ์ถ) ๊ธฐ์ค ์ ๋ ฌ
| ๊ฐ | ์ค๋ช |
|---|---|
flex-start |
์์์ ์ ๋ ฌ |
flex-end |
๋์ ์ ๋ ฌ |
center |
์ค์ ์ ๋ ฌ |
space-between |
์ ๋ ์ ๋ ฌ + ์์ดํ ์ฌ์ด ๋์ผ ๊ฐ๊ฒฉ |
space-around |
์์ดํ ์์ชฝ์ ๋์ผ ๊ฐ๊ฒฉ |
space-evenly |
์์ดํ ์ฌ์ด์ฌ์ด ํฌํจํ ๊ฐ๊ฒฉ์ด ๋์ผ |
.container {
justify-content: center;
}
๐งฒ 3. align-items
Cross Axis(๊ต์ฐจ ์ถ) ๊ธฐ์ค ์ ๋ ฌ (ํ ์ค์ผ ๋)
| ๊ฐ | ์ค๋ช |
|---|---|
stretch |
(๊ธฐ๋ณธ๊ฐ) ์์ดํ ์ ์ปจํ ์ด๋์ ๊ฝ ์ฐจ๊ฒ ๋๋ฆผ |
flex-start |
์์์ ์ ๋ ฌ |
flex-end |
๋์ ์ ๋ ฌ |
center |
์ค์ ์ ๋ ฌ |
baseline |
ํ ์คํธ ๊ธฐ์ค์ ์ ๋ ฌ |
.container {
align-items: stretch;
}
๐ 4. flex-wrap
์์ดํ ์ด ๋์น ๊ฒฝ์ฐ ์ค๋ฐ๊ฟ ์ฌ๋ถ๋ฅผ ์ค์
| ๊ฐ | ์ค๋ช |
|---|---|
nowrap |
์ค๋ฐ๊ฟ ์ ํจ (๊ธฐ๋ณธ๊ฐ) |
wrap |
์๋ ์ค๋ฐ๊ฟ |
wrap-reverse |
๋ฐ๋ ๋ฐฉํฅ์ผ๋ก ์ค๋ฐ๊ฟ |
.container {
flex-wrap: wrap;
}
๐ง 5. align-content
์ฌ๋ฌ ์ค์ผ ๊ฒฝ์ฐ, ์ค ์ ์ฒด์ ๋ํ ๊ต์ฐจ์ถ ์ ๋ ฌ ๋ฐฉ์ ์ง์
.container {
align-content: space-between;
}
align-items๋ โ์์ดํ โ ์ ๋ ฌ์ด๊ณ
align-content๋ โ์ค ์ ์ฒดโ ์ ๋ ฌ
๐ 6. ๊ฐ๋ณ ์์ดํ
์ ๋ ฌ - align-self
ํน์ ์์ดํ ๋ง ๊ฐ๋ณ์ ์ผ๋ก ๊ต์ฐจ์ถ ์ ๋ ฌ์ ์กฐ์ ํ ๋ ์ฌ์ฉ
.item {
align-self: flex-end;
}
๐งช Flex ์์ฑ ์์
.container {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
}
<div class="container">
<div class="item">Box 1</div>
<div class="item">Box 2</div>
<div class="item">Box 3</div>
</div>
๐ก Flex ์์ดํ ์ ์ฉ ์์ฑ
| ์์ฑ | ์ค๋ช |
|---|---|
flex-grow |
๋จ์ ๊ณต๊ฐ์ ์ผ๋ง๋ ํ์ฅํ ์ง |
flex-shrink |
๊ณต๊ฐ ๋ถ์กฑ ์ ์ค์ด๋๋ ๋น์จ |
flex-basis |
์์ดํ ์ ๊ธฐ๋ณธ ํฌ๊ธฐ |
.item {
flex: 1; /* flex-grow: 1, shrink: 1, basis: 0 */
}
โญ๏ธ ์ ๋ฆฌ
- Flexbox๋ ์์์ ์ ๋ ฌ๊ณผ ๋ฐฐ์น๋ฅผ ํ ์ฐจ์์์ ํจ์จ์ ์ผ๋ก ์ฒ๋ฆฌ
- ์ถ ๊ฐ๋ (Main / Cross)์ดํด ํ์
๐ผ๏ธ styled-components๋?
styled-components๋ CSS-in-JS ๋ฐฉ์์ ์คํ์์ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋๋ค.
JavaScript ํ์ผ ์์์ CSS๋ฅผ ์์ฑํ๊ณ , ์ด๋ฅผ ์ปดํฌ๋ํธ ํํ๋ก ์ฌ์ฉํ๋ ๊ฒ์ด ํต์ฌ
- React์ ๋งค์ฐ ์ ์ด์ธ๋ฆฌ๋ ์คํ์ผ๋ง ๋ฐฉ์
- ์ฝ๋์ ์คํ์ผ์ด ํจ๊ป ์์ผ๋ฏ๋ก ์ ์ง๋ณด์๊ฐ ์ฉ์ด
โจ ๊ธฐ๋ณธ ์ฌ์ฉ๋ฒ
import styled from 'styled-components';
const Title = styled.h1`
color: #fff;
background: #333;
padding: 20px;
border-radius: 8px;
`;
function App() {
return <Title>Hello, styled-components!</Title>;
}
styled.h1โ HTML ํ๊ทธ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์คํ์ผ ์ปดํฌ๋ํธ๋ฅผ ์์ฑ- ๋ฐฑํฑ(```) ์์ CSS ๋ฌธ๋ฒ ๊ทธ๋๋ก ์์ฑ
๐ฏ props๋ก ์คํ์ผ ๋์ ์ ์ด
styled-components๋ props๋ฅผ ํ์ฉํด ์คํ์ผ๋ ๋์ ์ผ๋ก ๋ฐ๊ฟ ์ ์๋ค.
const Button = styled.button`
background: ${(props) => (props.primary ? "blue" : "gray")};
color: white;
padding: 10px 20px;
border: none;
`;
function App() {
return (
<><Button>Default</Button>
<Button primary>Primary</Button>
</>
);
}
props.primary๊ฐ์ ๋ฐ๋ผ ๋ฒํผ ์์์ด ๋ฐ๋- ์กฐ๊ฑด๋ถ ์คํ์ผ๋ง์ JS ๋ก์ง์ฒ๋ผ ์์ฑํ ์ ์์
๐ ์คํ์ผ ํ์ฅํ๊ธฐ
๊ธฐ์กด ์คํ์ผ๋ ์ปดํฌ๋ํธ๋ฅผ ์ฌ์ฌ์ฉ ๋ฐ ํ์ฅํ ์ ์์ต๋๋ค.
const Button = styled.button`
padding: 10px;
background: #ccc;
`;
const RoundButton = styled(Button)`
border-radius: 20px;
`;
RoundButton์Button์ ์คํ์ผ์ ๊ธฐ๋ฐ์ผ๋ก ํ์ฅ- ๊ณตํต ์คํ์ผ์ ๋ถ๋ฆฌํ ๋ ๋งค์ฐ ์ ์ฉ
๐ ์ ์ญ ์คํ์ผ ์ค์ - createGlobalStyle
import { createGlobalStyle } from 'styled-components';
const GlobalStyle = createGlobalStyle`
body {
margin: 0;
background: #f5f5f5;
font-family: 'Noto Sans KR', sans-serif;
}
`;
function App() {
return (
<><GlobalStyle />
<Main />
</>
);
}
GlobalStyle์ ํตํด ์ ์ฒด ์ฑ์ ๊ณตํต ์คํ์ผ ์ ์ฉ ๊ฐ๋ฅApp์ปดํฌ๋ํธ ๋ฃจํธ์์ ํ ๋ฒ๋ง ํธ์ถ
โญ๏ธ ์ ๋ฆฌ
| ์ฅ์ | ์ค๋ช |
|---|---|
| ์ปดํฌ๋ํธ ๊ธฐ๋ฐ | ์คํ์ผ๋ ์ปดํฌ๋ํธ๋ก ๊ด๋ฆฌ ๊ฐ๋ฅ |
| CSS ๋ฌธ๋ฒ ๊ทธ๋๋ก | ๋ฐ๋ก ๋ฌธ๋ฒ์ ๋ฐฐ์ธ ํ์ ์์ |
| props ํ์ฉ | ์กฐ๊ฑด๋ถ ์คํ์ผ๋ง ๊ฐ๋ฅ |
| JS์์ ํตํฉ | ๋์ ๋ก์ง ๊ตฌํ ๊ฐ๋ฅ |