React์ Composition vs Inheritance ๐
React ๊ฐ๋ฐ์ ๋ฌธ์์ Composition vs Inheritance ์น์ ์ ์ปดํฌ๋ํธ๋ฅผ ์ฌ์ฌ์ฉํ๊ณ ํ์ฅํ๋ ๋ฐฉ๋ฒ์ ๋ํด ๋ค๋ฃน๋๋ค. ์ด ๋ฌธ์์์๋ **์ปดํฌ์ง์ (Composition)**์ด **์์(Inheritance)**๋ณด๋ค React์ ์ฒ ํ์ ๋ ์ ํฉํ ์ ๊ทผ ๋ฐฉ์์ด๋ผ๋ ์ ์ ๊ฐ์กฐํฉ๋๋ค. ์ด ๊ธ์์๋ React ๊ณต์ ๋ฌธ์๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๋ด์ฉ์ ์ ๋ฆฌํ๋ฉด์ ๋ ํ๋ถํ ์ฌ๋ก์ ์ค๋ช ์ ์ถ๊ฐํด ๋ณด๊ฒ ์ต๋๋ค. ๐
1๏ธโฃ ์ปดํฌ์ง์ (Composition)์ด๋?
์ปดํฌ์ง์ ์ React์์ ์ปดํฌ๋ํธ๋ฅผ ์ฌ์ฌ์ฉํ๊ณ ์กฐํฉํ๋ ๊ฐ์ฅ ๊ถ์ฅ๋๋ ๋ฐฉ๋ฒ์ ๋๋ค. ์ปดํฌ๋ํธ๋ฅผ ์๋ก ์กฐํฉํ์ฌ ๋ ํฐ ์ปดํฌ๋ํธ๋ฅผ ๊ตฌ์ฑํ๋ ๋ฐฉ์์ด์ฃ .
๐ ๏ธ ์ปดํฌ์ง์ ์ ํต์ฌ ๋ฐฉ์
React์์ ์ปดํฌ์ง์ ์ ๋ณดํต props.children๊ณผ ๊ฐ์ ํน์ prop ๋๋ ์ฝ๋ฐฑ ํจ์๋ฅผ ํตํด ๊ตฌํ๋ฉ๋๋ค.
์์ 1: props.children ํ์ฉ
function Card({ children }) {
return <div className="card">{children}</div>;
}
function App() {
return (
<Card>
<h1>React Composition</h1>
<p>์ปดํฌ์ง์ ์ ์์๋ณด๋ค ๋ ์ ์ฐํด์!</p>
</Card>
);
}
์์ 2: ํน์ ์์ญ์ ์ฝ์ ํ๊ธฐ
function SplitPane({ left, right }) {
return (
<div className="split-pane">
<div className="left-pane">{left}</div>
<div className="right-pane">{right}</div>
</div>
);
}
function App() {
return (
<SplitPane
left={<p>์ผ์ชฝ ์ฝํ ์ธ </p>}
right={<p>์ค๋ฅธ์ชฝ ์ฝํ ์ธ </p>}
/>
);
}
๐ ์ฅ์
1. ์ ์ฐ์ฑ: ๊ฐ ์ปดํฌ๋ํธ๋ ์์ ์ ์ญํ ๋ง ๋ด๋นํ๋ฉฐ, ์ธ๋ถ์์ ๋ฐ์ดํฐ๋ฅผ ์ฃผ์ ๋ฐ์ ์กฐ๋ฆฝ๋ฉ๋๋ค.
2. ์ฌ์ฌ์ฉ์ฑ: ์์ ์ปดํฌ๋ํธ๋ฅผ ์ฌ๋ฌ ๊ณณ์์ ์ฝ๊ฒ ์ฌ์ฌ์ฉํ ์ ์์ต๋๋ค.
3. React์ ์ฒ ํ์ ๋ถํฉ: React๋ UI๋ฅผ ์กฐํฉ ๊ฐ๋ฅํ ์ปดํฌ๋ํธ๋ก ๋๋์ด ๊ด๋ฆฌํ๋ ๊ฒ์ ๊ฐ์กฐํฉ๋๋ค.
2๏ธโฃ ์์(Inheritance)์ด๋?
์์์ ํด๋์ค ๊ธฐ๋ฐ ํ๋ก๊ทธ๋๋ฐ์์ ๋ถ๋ชจ-์์ ๊ด๊ณ๋ฅผ ์ ์ํ์ฌ ์์ฑ๊ณผ ๋ฉ์๋๋ฅผ ๊ณต์ ํ๋ ๋ฐฉ์์ ๋๋ค. ํ์ง๋ง React์์๋ ์์๋ณด๋ค๋ ์ปดํฌ์ง์ ์ ์ฌ์ฉํ๋ ๊ฒ์ด ๊ถ์ฅ๋ฉ๋๋ค.
๐ ๏ธ React์์ ์์ ์ฌ์ฉ ์์
class Button extends React.Component {
render() {
return <button>{this.props.label}</button>;
}
}
class SubmitButton extends Button {
render() {
return <button>{this.props.label || "Submit"}</button>;
}
}
๐ซ React์์ ์์์ ์ง์ํ๋ ์ด์
1. ๊ตฌ์กฐ๊ฐ ๋ณต์กํด์ง: ์์ ๊ณ์ธต์ด ๊น์ด์ง๋ฉด ์ปดํฌ๋ํธ ๊ฐ์ ๊ด๊ณ๋ฅผ ์ดํดํ๊ธฐ ์ด๋ ค์์ง๋๋ค.
2. ์ ์ฐ์ฑ ๋ถ์กฑ: ์์์ ์ปดํฌ๋ํธ์ ์ญํ ์ ๊ณ ์ ์ํค๋ ๊ฒฝํฅ์ด ์์ด ์ฌ์ฌ์ฉ์ฑ์ ๋จ์ด๋จ๋ฆฝ๋๋ค.
3. React์ ์ฒ ํ๊ณผ ์ด๊ธ๋จ: React๋ โํฉ์ฑโ์ ํตํ ์กฐ๋ฆฝํ ์ค๊ณ๋ฅผ ๊ถ์ฅํฉ๋๋ค.
3๏ธโฃ React์์ ์์๋ณด๋ค ์ปดํฌ์ง์ ์ ์ ํธํ๋ ์ด์
React๋ UI๋ฅผ ๊ตฌ์ฑ ๊ฐ๋ฅํ ์ปดํฌ๋ํธ๋ก ๋๋๋ ๋ฐ ์ค์ ์ ๋ก๋๋ค. ์์๋ณด๋ค ์ปดํฌ์ง์ ์ ์ ํธํ๋ ์ด์ ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
โ ์ปดํฌ์ง์ ์ ์ฅ์
โข ๊ตฌ์ฑ ๊ฐ๋ฅ์ฑ: ์ฌ๋ฌ ์ปดํฌ๋ํธ๋ฅผ ์กฐํฉํด ๋ณต์กํ UI๋ฅผ ์ฝ๊ฒ ๊ตฌ์ฑํ ์ ์์ต๋๋ค.
โข ๋ถ๋ฆฌ๋ ์ฑ ์: ๊ฐ ์ปดํฌ๋ํธ๋ ๋ ๋ฆฝ์ ์ผ๋ก ๋์ํ๋ฉฐ ์์ ์ ์ญํ ๋ง ์ํํฉ๋๋ค.
โข ํ ์คํธ ์ฉ์ด์ฑ: ์์ ์ปดํฌ๋ํธ๋ ํ ์คํธํ๊ธฐ ์ฝ์ต๋๋ค.
โข ์ฝ๋ ๊ฐ์ํ: ์์ ๊ณ์ธต์ ํผํ๋ฉด์ ๋จ์ํ๊ณ ์ง๊ด์ ์ธ ์ฝ๋ ๊ตฌ์กฐ๋ฅผ ์ ์งํ ์ ์์ต๋๋ค.
4๏ธโฃ ์ค์ ํ์ฉ: ์ปดํฌ์ง์ ์ ํ์ฉํ ๋ค์ํ ์ฌ๋ก
๐ ์ปจํธ๋กค๋๋ ์ปดํฌ๋ํธ์ ์ฌ๋กฏ ํจํด
์ปดํฌ์ง์ ์ ์์ฃผ ์ฌ์ฉํ๋ ์ปจํธ๋กค๋๋ ์ปดํฌ๋ํธ๋ ์ฌ๋กฏ ํจํด์์๋ ๋งค์ฐ ์ ์ฉํฉ๋๋ค.
์ปจํธ๋กค๋๋ ์ปดํฌ๋ํธ
function Input({ label, value, onChange }) {
return (
<label>
{label}
<input value={value} onChange={onChange} />
</label>
);
}
function App() {
const [name, setName] = React.useState("");
return (
<Input
label="Name:"
value={name}
onChange={(e) => setName(e.target.value)}
/>
);
}
์ฌ๋กฏ ํจํด
function Modal({ header, footer, children }) {
return (
<div className="modal">
<div className="header">{header}</div>
<div className="content">{children}</div>
<div className="footer">{footer}</div>
</div>
);
}
function App() {
return (
<Modal
header={<h2>๋ชจ๋ฌ ์ ๋ชฉ</h2>}
footer={<button>๋ซ๊ธฐ</button>}
>
<p>์ฌ๊ธฐ์ ๋ชจ๋ฌ ๋ด์ฉ์ด ๋ค์ด๊ฐ๋๋ค!</p>
</Modal>
);
}
5๏ธโฃ ์ปดํฌ์ง์ ๊ณผ ์์์ ํผ์ฉ์ ๊ฐ๋ฅํ ๊น?
React์์๋ ์์์ ์ ์ฌ์ฉํ์ง ์์ง๋ง, ํน์ ์ํฉ์์๋ ์ ํ์ ์ผ๋ก ํ์ฉํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, ๊ณตํต์ ์ธ ๋ฉ์๋๊ฐ ํ์ํ ๋ ์์์ ์ฌ์ฉํ ์๋ ์์ง๋ง, ๋๋ถ๋ถ์ ๊ฒฝ์ฐ HOC(Higher-Order Component) ๋๋ Hook์ผ๋ก ๋์ฒดํ ์ ์์ต๋๋ค.
6๏ธโฃ ์ปดํฌ์ง์ vs ์์: ์ธ์ ์ด๋ค ๊ฒ์ ์ฌ์ฉํด์ผ ํ ๊น?
โข ์ปดํฌ์ง์ ์ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ:
โข ์ปดํฌ๋ํธ ๊ฐ์ ๊ด๊ณ๊ฐ ๋์จํ๊ณ , ๋ ๋ฆฝ์ ์ผ๋ก ๋์ํ ๋.
โข ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ UI ์ปดํฌ๋ํธ๋ฅผ ๋ง๋ค๊ณ ์ถ์ ๋.
โข ์์์ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ:
โข ์์ฃผ ๋๋ฌผ๊ฒ, ๊ณตํต์ ์ธ ๋ก์ง์ด ๊ฐํ๊ฒ ๊ฒฐํฉ๋์ด ์์ด์ผ ํ๋ ์ํฉ์์๋ง ์ฌ์ฉ.
๊ฒฐ๋ก : React ๊ฐ๋ฐ์์ ์ ํ์?
React์์๋ ์ปดํฌ์ง์ ์ ๊ธฐ๋ณธ์ผ๋ก ์ผ๊ณ , UI๋ฅผ ์กฐ๋ฆฝ ๊ฐ๋ฅํ ๋ธ๋ก์ฒ๋ผ ์ค๊ณํ๋ ๊ฒ์ ๊ถ์ฅํฉ๋๋ค. ์์์ ํน์ ๊ฒฝ์ฐ์๋ง ์ ํ์ ์ผ๋ก ์ฌ์ฉํ๋ ๊ฒ์ด ์ข์์.
๐ท์ ์ค์ ๊ฐ๋ฐ์๊ฐ ๋์ด๋ด ์๋น!๐ท