Custom Hook
์ฌ์ฉ์๊ฐ ์ง์ ์ ์ํด์ ์ฌ์ฉํ๋ Hook์ผ๋ก use๋ก ์์ํ๋ ์ด๋ฆ์ ์ง์ด์ฃผ๋ฉด ๋๋ค.
์ค๋ณต ๋๋ ๋ถ๋ถ์ ํ ์ผ๋ก ๋ง๋ค์ด์ ์ฌ์ฌ์ฉ์ฑ, ์ ์ง ๋ณด์์ฑ ๋ฐ ์ฝ๋ ๊ฐ๋ ์ฑ์ ๋์ผ ์ ์๋ค๋ ์ฅ์ ์ด ์๋ค.
์์ - Counter
+, - ๋ฒํผ์ผ๋ก ์ซ์๋ฅผ ์ฆ๊ฐ ๊ฐ์ ์ํค๋ ๋ค์๊ณผ ๊ฐ์ ์ฝ๋๊ฐ ์๋ค๊ณ ํ ๋,
์ปค์คํ ํ ์ ์ฌ์ฉํ์ง ์์ ๊ฒฝ์ฐ (์ปดํฌ๋ํธ ์์ฑ)
- UI์ ์ํ๊ฐ ๊ฒฐํฉ๋ผ ์ฌ์ฌ์ฉ์ด ์ด๋ ค์ (App ์ปดํฌ๋ํธ์ return๋ฌธ์์ ์ฌ๋ฌ๋ฒ ๋ถ๋ฌ์ค๋ฉด ์ฌ๋ฌ ๊ฐ ์ธ์๋ ์๋ค...)
- ๋ง์ฝ ๋๊ฐ์ ๋ก์ง์ ๋ค๋ฅธ ์ปดํฌ๋ํธ์์ ์ฐ๋ ค๋ฉด ๋ณต๋ถํด์ ์ฌ์ฉํด์ผํจ
- ์ปดํฌ๋ํธ๋ ๋ณธ์ง์ ์ผ๋ก๋ UI๋ฅผ ๊ตฌ์ฑํ๋ ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ ์กฐ๊ฐ์ด๊ธฐ ๋๋ฌธ์ ์ฒ๋ฆฌ ๋ก์ง, ์ํ ๋ฑ์ด ๋ณต์กํด์ง๋ฉด ์ปดํฌ๋ํธ๊ฐ ๋ณต์กํด์ง
function App() {
return (
<>
<Counter />
</>
);
}
const Counter = () => {
const [counter, setCounter] = useState(0);
return (
<>
<div>counter : {counter}</div>
<button onClick={() => setCounter((prev) => prev + 1)}>+</button>
<button onClick={() => setCounter((prev) => prev - 1)}>-</button>
</>
);
};
์ปค์คํ ํ ์ ์ฌ์ฉํ ๊ฒฝ์ฐ
์ ์ฝ๋์ ๊ฐ์ ๊ธฐ๋ฅ์์ ์ฆ๊ฐํญ์ ์ค์ ํ๋ ๊ฒ๊น์ง ์ถ๊ฐํ๋ค.
- useCounter()๋ฅผ ํธ์ถ๋ง ํ๋ฉด ์ด๋์๋ ์ํ๋ฅผ ๋๊ฐ์ด ์ธ ์ ์์ด์ ์ฌ์ฌ์ฉ์ฑ์ด ๋งค์ฐ ์ข์์ง
- ๋ ผ๋ฆฌ๋ฅผ ๋ถ๋ฆฌํด์ ๊ด๋ฆฌ๊ฐ ๊ฐ๋ฅํจ
- ์ปค์คํ ํ ์ ๋ฐ๋ณต์ ์ผ๋ก ์ฌ์ฉ๋๋ ๋ก์ง์ ์ฌ์ฌ์ฉํ๊ธฐ ์ํด ์์ฑ
- ์ธ์๋ก ์ค์ ์ด ๊ฐ๋ฅํด(์๋ ์ฝ๋์์๋ ์ด๊ธฐ๊ฐ, step) ์ ์ฐ์ฑ์ด ์ข์์ง
function App() {
// ์ด๊ธฐ๊ฐ์ 0, step์ 3์ฉ ์ฆ/๊ฐ
// ๊ตฌ์กฐ๋ถํดํ ๋น์ผ๋ก ์ธ ๊ฐ์ฒด๋ฅผ ๋ฐ์์ด!
const { count, increment, decrement } = useCounter(0, 3);
return (
<>
<div>
<div>custom Hook counter : {count}</div>
<button onClick={increment}>+</button>
<button onClick={decrement}>-</button>
</div>
</>
);
}
// ์ปค์คํ
ํ
ํจ์ ์ ์
// initialValue : ๊ธฐ๋ณธ๊ฐ์ 0, ์นด์ดํฐ ์์ ์ซ์
// step : ๋ณํ ํญ
const useCounter = (initialValue = 0, step) => {
// count ์ํ ์์ฑ
const [count, setcount] = useState(initialValue);
// ๊ฐ๊ฐ ์ฆ๊ฐ, ๊ฐ์ ํจ์
const increment = () => setcount((prev) => prev + step);
const decrement = () => setcount((prev) => prev - step);
// ์ธ๋ถ์์ ์ฌ์ฉํ ์ ์๋๋ก count, increment, decrement๋ฅผ ๊ฐ์ฒด ํํ๋ก ๋ฐํ
return { count, increment, decrement };
};
์์ - ์ธ๋ถ ๋ฐ์ดํฐ ๋ฐ์์ค๊ธฐ
json-server๋ฅผ ์ด์ฉํด ์ธ๋ถ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์์ค๋ ์ฐ์ต์ด๋ค.
์ด๋ฒ์ db.json, db1.json, db2.json ํ์ผ ์ธ๊ฐ๋ฅผ ๋ง๋ค์ด์ ๊ฐ๊ฐ ๋ค๋ฅธ ๋ฐ์ดํฐ๋ฅผ ๋ฃ์ด์คฌ๊ณ ๋๋ฌธ์ ํฌํธ ๋ฒํธ๋ 3000, 3001, 3002๋ก ๋ค๋ฅด๊ฒ ์คํํ๋ค.
function App() {
// error๋ ์ฐ์ง ์์ผ๋ฏ๋ก loading:loading1, data:data1 ์ด๋ฐ์์ผ๋ก ๊ตฌ์กฐ ๋ถํด ํ ๋นํ๋ฉด์ ๋ณ์ ์ด๋ฆ ๋ฐ๊พธ๊ธฐ๋ ํด์ค์ผํจ
const { loading: loading1, data: data1 } = useFetch(
'http://localhost:3000/data',
);
const { loading: loading2, data: data2 } = useFetch(
'http://localhost:3001/data',
);
const { loading: loading3, data: data3 } = useFetch(
'http://localhost:3002/data',
);
return (
<>
{!loading1 && ( // ๋ก๋ฉ ์ค์ด ์๋๋ผ๋ฉด (loading1์ด false๋ผ๋ฉด)
<ul>
{data1.map((el) => (
<li key={'data1' + el.id}>{el.content}</li>
))}
</ul>
)}
{!loading2 && ( // ๋ก๋ฉ ์ค์ด ์๋๋ผ๋ฉด (loading2๊ฐ false๋ผ๋ฉด)
<ul>
{data2.map((el) => (
<li key={'data1' + el.id}>{el.content}</li>
))}
</ul>
)}
{!loading3 && ( // ๋ก๋ฉ ์ค์ด ์๋๋ผ๋ฉด (loading3์ด false๋ผ๋ฉด)
<ul>
{data3.map((el) => (
<li key={'data1' + el.id}>{el.content}</li>
))}
</ul>
)}
</>
);
}
const useFetch = (url) => {
// ๋ก๋ฉ ์ํ ๊ด๋ฆฌ
const [loading, setLoading] = useState(true);
// ๋ฐ์ดํฐ์ ์ํ ๊ด๋ฆฌ
const [data, setData] = useState(null);
// ์๋ฌ ์ํ ๊ด๋ฆฌ
const [error, setError] = useState(null);
useEffect(() => {
fetch(url)
// json->javascript ๊ฐ์ฒด ํ์
์ผ๋ก ๋ณ๊ฒฝํด์ ๋ฐ์์ด
.then((res) => res.json())
// ๋ฐ์์จ ๋ฐ์ดํฐ๋ฅผ setData๋ก data ์
๋ฐ์ดํธ
.then((res) => {
setData(res);
setLoading(false);
})
// ์๋ฌ ๋ฐ์ ์
.catch((err) => {
setError(err);
setLoading(false);
});
// ๋ฐ์์ค๋ url์ ๋ฐ๋ผ ์คํ๋๊ธฐ ๋๋ฌธ์ ์์กด์ฑ ๋ฐฐ์ด์ url ์ถ๊ฐ
}, [url]);
// ๋ก๋ฉ ์ํ, ๋ฐ์ดํฐ, ์๋ฌ ์ฌ๋ถ๋ฅผ ๋ฐํ
return { loading, data, error };
};
'react' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
React / ์คํ์ผ๋ง (2) - Styled Components (1) | 2025.04.16 |
---|---|
React / ์คํ์ผ๋ง (1) - SCSS (0) | 2025.04.15 |
React / useRef (0) | 2025.04.11 |
React / ์๋ช ์ฃผ๊ธฐ (0) | 2025.04.10 |
React / Router ์ค์ต - ๋๋ฌผ ์ ๋ณด ์ฌ์ดํธ ๋ง๋ค๊ธฐ (0) | 2025.04.09 |