์ฐธ๊ณ ์ฌ์ดํธ
• ๋ฆฌ์กํธ ๊ณต์ ๋ฌธ์ - Custom Hook
โ๏ธ Custom Hook
์์ ๊ฒ์๊ธ์์ ๋ค์ํ Hook์ ์ฌ์ฉํด์๋ค.
React์๋ useState, useContext, useEffect์ ๊ฐ์ ์ฌ๋ฌ ๋ด์ฅ Hook์ด ํจ๊ป ์ ๊ณต๋๋ค.
๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๊ฑฐ๋, ์ฌ์ฉ์๊ฐ ์จ๋ผ์ธ ์ํ์ธ์ง ์ถ์ ํ๊ฑฐ๋ ์ฑํ ๋ฐฉ์ ์ฐ๊ฒฐํ๋ ๋ฑ ์ข ๋ ๊ตฌ์ฒด์ ์ธ ๋ชฉ์ ์ ์ํด Hook์ด ์์์ผ๋ฉด ํ๋ ๊ฒฝ์ฐ๊ฐ ์๋ค.
React์์ ์ด๋ฌํ Hook์ ๋ชจ๋ ์ง์ํ ์ ์๋ค.
๊ทธ๋์ ์ดํ๋ฆฌ์ผ์ด์ ์๊ตฌ์ฌํญ์ ๋ง๊ฒ ์ง์ ์์ ๋ง์ Hook์ ๋ง๋ค ์ ์๋ค.
๐ง ์ ์ฌ์ฉํ ๊น?
- ์ฌ์ฌ์ฉ์ฑ์ด ๋์ ์ฝ๋๊ฐ ๊ฐ๊ฒฐํด์ง๋ค.
- ๋ด์ฅ Hook์ ์ฌ์ฉํ ์ ์๋ค.
- ๋ ๋ฆฝ์ ์ผ๋ก ๋์ํ๋ค.
๐ก ๊ตฌ์ฑ์์ ๊ฐ ๋ ผ๋ฆฌ ๊ณต์
๋คํธ์ํฌ์ ํฌ๊ฒ ์์กดํ๋ ์ฑ์ด ์๋ค๊ณ ์์ํด๋ณด์.
์ฑ์ ์ฌ์ฉํ๋ ๋์ ๋คํธ์ํฌ ์ฐ๊ฒฐ์ด ๋์ด์ก์ ๊ฒฝ์ฐ ์ฌ์ฉ์์๊ฒ ๊ฒฝ๊ณ ๋ฅผ ๋ณด๋ด๊ณ ์ถ๋ค๋ฉด ์ด๋ป๊ฒ ํด์ผํ ๊น
- ๋คํธ์ํฌ๊ฐ ์จ๋ผ์ธ์ธ์ง ์ฌ๋ถ๋ฅผ ์ถ์ ํ๋ ์ํ
- ์ ์ญ์์ *online ๋ฐ *offline ์ด๋ฒคํธ๋ฅผ ๊ตฌ๋ ํ๊ณ ํด๋น ์ํ๋ฅผ ์ ๋ฐ์ดํธํ๋ค.
์ด๋ ๊ฒํ๋ฉด ๊ตฌ์ฑ์์๊ฐ ๋คํธ์ํฌ ์ํ์ ๋๊ธฐํ๋ ์ํ๋ก ์ ์ง๋๋ค.
*online: ๋ธ๋ผ์ฐ์ ๊ฐ ๋คํธ์ํฌ์ ๋ํ ์ก์ธ์ค๊ฐ์ด true๋ก ๋ณ๊ฒฝ๋๋ฉด ์ด๋ฒคํธ๊ฐ ์์๋๋ค.
*offline: ๋ธ๋ผ์ฐ์ ๊ฐ ๋คํธ์ํฌ์ ๋ํ ์ก์ธ์ค๊ฐ์ด ์์คํ์ฌ ๊ฐ์ด false๋ก ๋ณ๊ฒฝ๋๋ฉด ์ด๋ฒคํธ๊ฐ ์์๋๋ค.
์ถ์ฒ : M mdn web docs (mozilla)
๊ทธ๋ผ window์ addEventListener๋ฅผ ํตํด ์ด๋ฒคํธ๋ฅผ ์ถ๊ฐํด๋ณด์.
๐ฅ๏ธ Code
๋ฌธ๋ ๊ณต์๋ฌธ์ ์์๋ฅผ ๋ฐ๋ผํด๋ณด๋ค๊ฐ ๊ถ๊ธ์ ์ด ์๊ฒผ๋ค.
๋ฐ๋ผํ ์๋ณธ์ ๊ฐ์ ์ฝ๋๋ฅผ ๋ฃ์ด๋๊ณ ๊ฐ๋ฐํ ๋ฒ์ ์ด๋ค.
์ ํํ Custom Hook์ ๋ณด๊ณ ์ํ๋ฉด ๐ท๐ปโ๏ธ ๋ณด์ผ ๋๊น์ง ์คํฌ๋กค์ ํ๋ฉด ๋๋ค.
์ฝ๋ ์ฌ์ฉ ์, MUI ํ๊ฒฝ์ ์ค์น๊ฐ ํ์ํ๋ค.
๐ App.tsx
import "./App.css";
import { NetworkObserver } from "./NetworkObserver";
import { NetworkCommunication } from "./NetworkCommunication";
function App() {
return (
<>
<div className="App">
<NetworkObserver />
<NetworkCommunication />
</div>
</>
);
}
export default App;
๐NetworkObserver.tsx
import { useEffect, useState } from "react";
import WifiOutlinedIcon from "@mui/icons-material/WifiOutlined";
import WifiOffOutlinedIcon from "@mui/icons-material/WifiOffOutlined";
export function NetworkObserver() {
const [online, setOnline] = useState<boolean>(true);
useEffect(() => {
function handleOnline() {
setOnline(true);
}
function handleOffline() {
setOnline(false);
}
window.addEventListener("online", handleOnline);
window.addEventListener("offline", handleOffline);
return () => {
window.addEventListener("online", handleOnline);
window.addEventListener("offline", handleOffline);
};
}, []);
return (
<div>
{online ? (
<>
<WifiOutlinedIcon
sx={{ color: "skyblue", verticalAlign: "bottom" }}
/>
Connected
</>
) : (
<>
<WifiOffOutlinedIcon sx={{ verticalAlign: "bottom" }} /> Disconnected
</>
)}
</div>
);
}
๐NetworkCommunication.tsx
import { useEffect, useState } from "react";
export function NetworkCommunication() {
const [online, setOnline] = useState<boolean>(true);
useEffect(() => {
function handleOnline() {
setOnline(true);
}
function handleOffline() {
setOnline(false);
}
window.addEventListener("online", handleOnline);
window.addEventListener("offline", handleOffline);
return () => {
window.addEventListener("online", handleOnline);
window.addEventListener("offline", handleOffline);
};
}, []);
return <div>{online ? "Connected" : "DisConnected"}</div>;
}
์ฐ์ ๊ฐ๋ฐ ์๋ฒ๋ฅผ ์ด๊ธฐ ์ํด ์ธํฐ๋ท์ด ์ ์ ๋์ด ์์ ๊ฒ์ด๋ true๋ฅผ ๊ธฐ๋ณธ๊ฐ์ผ๋ก ๋์๋ค.
์ด์ ๋ณธ์ธ PC์์ Wi-Fi ์ฐ๊ฒฐ์ ํด์ ํ๊ฑฐ๋, ๋์ ์ ๋ฝ์๋ณด์.
window์ addEventListner๋ฅผ ํตํด ์ฐ๊ฒฐ์ด ๋์ด์ง๋ฉฐ online ์ํ ๊ฐ์ด false๋ก ๋ณ๊ฒฝ๋์ด ๋ฆฌ-๋ ๋๋ง์ด ๋๋ค.
์ด์ App.tsx์์ ๋ ์ปดํฌ๋ํธ๋ฅผ ํธ์ถํด์ฃผ๋ฉด ๋๋๋ฐ,
์ด๊ฑฐ๋ง๊ณ
๐ App.tsx
import { NetworkObserver } from "./NetworkObserver";
import "./App.css";
import { NetworkCommunication } from "./NetworkCommunication";
import { useEffect, useState } from "react";
function App() {
const [online, setOnline] = useState<boolean>(true);
function handleOnline() {
setOnline(true);
}
function handleOffline() {
setOnline(false);
}
useEffect(() => {
window.addEventListener("online", handleOnline);
window.addEventListener("offline", handleOffline);
return () => {
window.addEventListener("online", handleOnline);
window.addEventListener("offline", handleOffline);
};
}, []);
return (
<>
<div className="App">
<NetworkObserver online={online} />
<NetworkCommunication online={online} />
</div>
</>
);
}
export default App;
๐NetworkObserver.tsx
import { useEffect, useState } from "react";
import WifiOutlinedIcon from "@mui/icons-material/WifiOutlined";
import WifiOffOutlinedIcon from "@mui/icons-material/WifiOffOutlined";
export function NetworkObserver({ online }) {
return (
<div>
{online ? (
<>
<WifiOutlinedIcon
sx={{ color: "skyblue", verticalAlign: "bottom" }}
/>
</>
) : (
<>
<WifiOffOutlinedIcon sx={{ verticalAlign: "bottom" }} />
</>
)}
</div>
);
}
๐NetworkCommunication.tsx
export function NetworkCommunication({ online }) {
return <div>{online ? "Connected" : "Disconnected"}</div>;
}
์ด๋ ๊ฒ props๋ก ์ฃผ๋ฉด ๋ ๊ฑฐ ๊ฐ๊ฒฐํด์ง ๊ฑฐ ๊ฐ์์ ์๋ก์ด ์์ ๋ฅผ ์ฐพ์๋ดค๋ค.
๋์์ ๋๊ฐ์ด ์ ๋์ํ๋ค.
๋จ์ํ ๋คํธ์ํฌ ์ฐ๊ฒฐ์ด๋ผ ๊ทธ๋ฐ๊ฐ ์ถ๋ค๊ฐ
๐ง ๊ณ์ ๊ณ ๋ฏผํ๋ค ์ด๊ฒ ์ ์์ ๋ก ์์๊น...
์๊ฐํด๋ธ ๋ต์
์ต์๋จ State์์ ๋คํธ์ํน ๊ฐ์ด ๋ฐ๋๋ฉด ์ ๋ง์ prop์ ๋๊ฒจ๋ฐ๊ฑฐ๋ Context ํน์ recoil๋ก ๊ฐ์ ๊ณต์ ํ์ฌ ๊ฐ์ผ๋ก ๋ณ๊ฒฝํ ์ ์๊ฒ ์ง๋ง
Custom Hook ์ฝ๋๋ฅผ ๋ณด๊ณ ๋์ Custom Hook์ด ์ข ๋ ๊ฐ๊ฒฐํ๊ณ ๊ด์ฐฎ์ ๊ฑฐ๋ผ ์๊ฐํ๋ค.
์๋ํ๋ฉด React Hook์ ์ปดํฌ๋ํธ ์ด๋์๋ ํธ์ถ์ด ๊ฐ๋ฅํ๊ธฐ ๋๋ฌธ์ด๋ค.
โ๏ธ CustomHook ์ ์
React Hook์ ์ดํด๋ณด๋ฉด Hook์ ์ด๋ฆ๋ค์ ์์ use๊ฐ ๋ถ์ด์๋ ๊ฒ์ ํ์ธ ํ ์ ์๋ค.
ํ์ผ์ ์์ฑํ ๋, ํ์ผ๋ช ์ use๋ก ์์ํด์ ์์ฑํ๋ฉด ๋๋ค.
๐useNetwork.ts
import { useEffect, useState } from "react";
export function useNetwork() {
const [isOnline, setIsOnline] = useState<boolean>(true);
useEffect(() => {
function handleOnline() {
setIsOnline(true);
}
function handleOffline() {
setIsOnline(false);
}
window.addEventListener("online", handleOnline);
window.addEventListener("offline", handleOffline);
return () => {
window.addEventListener("online", handleOnline);
window.addEventListener("offline", handleOffline);
};
}, []);
return isOnline;
}
๐App.tsx
import "./App.css";
import { NetworkObserver } from "./NetworkObserver";
import { NetworkCommunication } from "./NetworkCommunication";
function App() {
return (
<>
<div className="App">
<NetworkObserver />
<NetworkCommunication />
</div>
</>
);
}
export default App;
๐NetworkObserver.tsx
import { useEffect, useState } from "react";
import WifiOutlinedIcon from "@mui/icons-material/WifiOutlined";
import WifiOffOutlinedIcon from "@mui/icons-material/WifiOffOutlined";
import { useNetwork } from "./useNetwork";
export function NetworkObserver() {
const online = useNetwork();
return (
<div>
{online ? (
<>
<WifiOutlinedIcon
sx={{ color: "skyblue", verticalAlign: "bottom" }}
/>
</>
) : (
<>
<WifiOffOutlinedIcon sx={{ verticalAlign: "bottom" }} />
</>
)}
</div>
);
}
๐NetworkCommunication.tsx
import { useNetwork } from "./useNetwork";
export function NetworkCommunication() {
const online = useNetwork();
return <div>{online ? "Connected" : "Disconnected"}</div>;
}
์ฝ๋๊ฐ ํ๊ฒฐ ๊ฐ๊ฒฐํด์ก์ผ๋ฉฐ,
๋๊ฐ์ด ์ ๋์ํ๋ค.
'Framework > React' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[React / Next.js] Atomic ๋์์ธ ํจํด์ ๋ํด ์์๋ณด์. (4) | 2024.09.21 |
---|---|
[ React ] useContext์ ๋ํด ์์๋ณด์. (2) | 2024.04.08 |
[ React ] useCallback์ ๋ํด ์์๋ณด์. (0) | 2024.04.05 |
[ React ] useMemo์ ๋ํด ์์๋ณด์. (0) | 2024.04.04 |
[ React ] useRef์ ๋ํด ์์๋ณด์. (0) | 2024.04.04 |