๐ญ ์กฐ๊ฑด๋ถ ๋ ๋๋ง ์ง์ฅ: ๋ณต์กํ ์ผํญ ์ฐ์ฐ์์ && ๋จ๋ฐ, ๊ฐ๋ ์ฑ ๋ฐ ์ ์ง๋ณด์์ฑ ์ ํ
Summary
๋ณต์กํ ์กฐ๊ฑด๋ถ ๋ ๋๋ง ๋ก์ง์ ์ผํญ ์ฐ์ฐ์๋ && ์ฐ์ฐ์๋ก ์ปดํฌ๋ํธ ๋ด๋ถ์ ๊ณผ๋ํ๊ฒ ๊ตฌํํ๋ฉด ์ฝ๋ ๊ฐ๋ ์ฑ, ์ ์ง๋ณด์์ฑ์ด ๋จ์ด์ง๊ณ ๋ฒ๊ทธ ๋ฐ์ ๊ฐ๋ฅ์ฑ์ด ๋์์ง๋๋ค. ์ปดํฌ๋ํธ ๋ถ๋ฆฌ, ํฌํผ ํจ์, HOC, Render Props ํจํด ๋ฑ์ ํตํด ์กฐ๊ฑด๋ถ ๋ ๋๋ง ๋ก์ง์ ๋ถ๋ฆฌํ๊ณ ์ฌ์ฌ์ฉ์ฑ์ ๋์ฌ์ผ ํฉ๋๋ค.
Why Wrong?
React ์ปดํฌ๋ํธ ๋ด์์ ๋ณต์กํ ์กฐ๊ฑด์ ๋ฐ๋ผ UI๋ฅผ ๋ ๋๋งํด์ผ ํ ๋, ์ผํญ ์ฐ์ฐ์(condition ? A : B
)๋ && ์ฐ์ฐ์๋ฅผ ๊ณผ๋ํ๊ฒ ์ค์ฒฉํ์ฌ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ๊ฐ ์์ต๋๋ค. ์ด๋ ์ฝ๋์ ๊ฐ๋
์ฑ์ ์ฌ๊ฐํ๊ฒ ์ ํ์ํค๊ณ , ์กฐ๊ฑด์ด ์กฐ๊ธ๋ง ๋ณ๊ฒฝ๋์ด๋ ์ฝ๋๋ฅผ ์ดํดํ๊ณ ์์ ํ๋ ๋ฐ ๋ง์ ์ด๋ ค์์ ๊ฒช๊ฒ ๋ง๋ญ๋๋ค. ํนํ ์ฌ๋ฌ ์ํ ๋ณ์์ ์์กดํ๋ ๋ณต์กํ ์กฐ๊ฑด์ ์ฝ๋ ์ ์ฒด๋ฅผ ํ์
ํ๊ธฐ ์ด๋ ต๊ฒ ๋ง๋ค์ด ๋ฒ๊ทธ ๋ฐ์ ๊ฐ๋ฅ์ฑ์ ๋์ด๊ณ , ์ ์ง๋ณด์ ๋น์ฉ์ ์ฆ๊ฐ์ํค๋ ์ฃผ๋ฒ์ด ๋ฉ๋๋ค. ์กฐ๊ฑด๋ถ ๋ ๋๋ง ๋ก์ง์ด ์ปดํฌ๋ํธ ๋ ๋๋ง ๋ก์ง๊ณผ ์์ด๋ฉด์ ์ปดํฌ๋ํธ์ ์ญํ ์ด ๋ชจํธํด์ง๊ณ , ์ฌ์ฌ์ฉ์ฑ ๋ํ ๋จ์ด๋จ๋ฆฝ๋๋ค.
How to Fix?
๋ณต์กํ ์กฐ๊ฑด๋ถ ๋ ๋๋ง ๋ก์ง์ ์ปดํฌ๋ํธ ๋ด๋ถ์์ ์ฒ๋ฆฌํ๋ ๋์ , ๋ค์๊ณผ ๊ฐ์ ๋ฐฉ๋ฒ์ ๊ณ ๋ คํด์ผ ํฉ๋๋ค.
- ์ปดํฌ๋ํธ ๋ถ๋ฆฌ: ์กฐ๊ฑด๋ณ๋ก ๋ ๋๋ง๋๋ ๋ถ๋ถ์ ๋ณ๋์ ์ปดํฌ๋ํธ๋ก ๋ถ๋ฆฌํ์ฌ ๊ฐ ์ปดํฌ๋ํธ๊ฐ ํน์ ์กฐ๊ฑด์ ๋ฐ๋ฅธ UI ๋ ๋๋ง๋ง์ ๋ด๋นํ๋๋ก ํฉ๋๋ค. ์ด๋ ๊ฐ ์ปดํฌ๋ํธ์ ์ฑ ์ ๋ฒ์๋ฅผ ๋ช ํํ ํ๊ณ , ์ฝ๋์ ๊ฐ๋ ์ฑ์ ๋์ฌ ์ ์ง๋ณด์๋ฅผ ์ฉ์ดํ๊ฒ ๋ง๋ญ๋๋ค.
- ํฌํผ ํจ์ ์ฌ์ฉ: ์กฐ๊ฑด๋ถ ๋ ๋๋ง ๋ก์ง์ ํฌํผ ํจ์๋ก ์ถ์ถํ์ฌ ์ปดํฌ๋ํธ ์ธ๋ถ์์ ์ฒ๋ฆฌํฉ๋๋ค. ํฌํผ ํจ์๋ ํน์ ์กฐ๊ฑด์ ๋ฐ๋ผ ๋ ๋๋งํ JSX๋ฅผ ๋ฐํํ๊ฑฐ๋, ์ปดํฌ๋ํธ props๋ฅผ ๋ณ๊ฒฝํ๋ ์ญํ ์ ์ํํ ์ ์์ต๋๋ค. ์ด๋ ์ปดํฌ๋ํธ ๋ด๋ถ์ ๋ณต์ก๋๋ฅผ ์ค์ด๊ณ , ํ ์คํธ ์ฉ์ด์ฑ์ ๋์ ๋๋ค.
- ๊ณ ์ฐจ ์ปดํฌ๋ํธ (HOC) ๋๋ Render Props: ํน์ ์กฐ๊ฑด์ ๋ฐ๋ผ ์ปดํฌ๋ํธ์ ๋ ๋๋ง ๋ก์ง์ ํ์ฅํ๊ฑฐ๋ ๋ณ๊ฒฝํด์ผ ํ๋ ๊ฒฝ์ฐ, ๊ณ ์ฐจ ์ปดํฌ๋ํธ๋ Render Props ํจํด์ ํ์ฉํ ์ ์์ต๋๋ค. ์ด๋ฅผ ํตํด ์กฐ๊ฑด๋ถ ๋ ๋๋ง ๋ก์ง์ ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ ํํ๋ก ์บก์ํํ๊ณ , ์ปดํฌ๋ํธ ๊ฐ์ ๊ฒฐํฉ๋๋ฅผ ๋ฎ์ถ ์ ์์ต๋๋ค.
Before Code (Bad)
function MyComponent({ isLoading, data, error, isAdmin }) {
return (
<div>
{isLoading ? (
<p>Loading...</p>
) : error ? (
<p>Error: {error.message}</p>
) : data ? (
isAdmin ? (
<div>
<h1>Welcome Admin</h1>
<p>Data: {data.value}</p>
<button>Edit</button>
</div>
) : (
<div>
<h1>Welcome User</h1>
<p>Data: {data.value}</p>
</div>
)
) : (
<p>No data available.</p>
)}
</div>
);
}
After Code (Good)
// ์ปดํฌ๋ํธ ๋ถ๋ฆฌ
function Loading() {
return <p>Loading...</p>;
}
function ErrorMessage({ error }) {
return <p>Error: {error.message}</p>;
}
function AdminView({ data }) {
return (
<div>
<h1>Welcome Admin</h1>
<p>Data: {data.value}</p>
<button>Edit</button>
</div>
);
}
function UserView({ data }) {
return (
<div>
<h1>Welcome User</h1>
<p>Data: {data.value}</p>
</div>
);
}
function NoData() {
return <p>No data available.</p>
}
function MyComponent({ isLoading, data, error, isAdmin }) {
if (isLoading) {
return <Loading />;
}
if (error) {
return <ErrorMessage error={error} />;
}
if (!data) {
return <NoData />
}
return isAdmin ? <AdminView data={data} /> : <UserView data={data} />;
}