반응형
useTitle
Title이 변할 때 변화를 감지하는 역할
import { StrictMode, useEffect, useState } from "react";
import { createRoot } from "react-dom/client";
const useTitle = (initialTitle) => {
const [title, setTitle] = useState(initialTitle);
const updateTitle = () => {
const htmlTitle = document.querySelector("title");
htmlTitle.innerText = title;
};
useEffect(updateTitle, [title]);
return setTitle;
};
const App = () => {
const titleUpdater = useTitle("Loading...");
setTimeout(() => titleUpdater("Home"), 5000);
return <div className="App">Hi</div>;
};
const rootElement = document.getElementById("root");
const root = createRoot(rootElement);
root.render(
<StrictMode>
<App />
</StrictMode>
);
useTabs
Tab이 변할 때 변화를 감지하는 역할
import { StrictMode, useState } from "react";
import { createRoot } from "react-dom/client";
const content = [
{
tab: "Section 1",
content: "IO'm the content 1",
},
{
tab: "Section 2",
content: "IO'm the content 2",
},
];
const useTabs = (initialTab, allTabs) => {
if (!allTabs || !Array.isArray(allTabs)) {
return;
}
const [currentIdx, setCurrentIdx] = useState(initialTab);
return {
currentItem: allTabs[currentIdx],
changeItem: setCurrentIdx,
};
};
const App = () => {
const { currentItem, changeItem } = useTabs(0, content);
return (
<div className="App">
{content.map((section, idx) => (
<button onClick={() => changeItem(idx)}>{section.tab}</button>
))}
<div>{currentItem.content}</div>
</div>
);
};
const rootElement = document.getElementById("root");
const root = createRoot(rootElement);
root.render(
<StrictMode>
<App />
</StrictMode>
);
useScroll
Scroll이 변할 때 변화를 감지하는 역할
import { StrictMode, useEffect, useState } from "react";
import { createRoot } from "react-dom/client";
const useScroll = () => {
const [state, setState] = useState({
x: 0,
y: 0,
});
const onScroll = () => {
console.log(`y : ${window.scrollY} x : ${window.scrollX}`);
setState({ y: window.scrollY, x: window.scrollX });
};
useEffect(() => {
window.addEventListener("scroll", onScroll);
return () => window.removeEventListener("scroll", onScroll);
}, []);
return state;
};
const App = () => {
const { y } = useScroll();
return (
<div className="App" style={{ height: "1000vh" }}>
<h1 style={{ position: "fixed", color: y > 100 ? "red" : "blue" }}>HI</h1>
</div>
);
};
const rootElement = document.getElementById("root");
const root = createRoot(rootElement);
root.render(
<StrictMode>
<App />
</StrictMode>
);
usePreventLeave
사용자가 창을 닫으려는 것을 감지하는 역할
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
const usePreventLeave = () => {
const listener = (e) => {
e.preventDefault();
e.returnValue = "";
};
const enablePrevent = () => window.addEventListener("beforeunload", listener);
const disablePrevent = () =>
window.removeEventListener("beforeunload", listener);
return { enablePrevent, disablePrevent };
};
const App = () => {
const { enablePrevent, disablePrevent } = usePreventLeave();
return (
<div className="App">
<button onClick={enablePrevent}>Protect</button>
<button onClick={disablePrevent}>unProtect</button>
</div>
);
};
const rootElement = document.getElementById("root");
const root = createRoot(rootElement);
root.render(
<StrictMode>
<App />
</StrictMode>
);
useBeforeLeave
현재 창에서 마우스가 벗어나는 것을 감지하는 역할
import { StrictMode, useEffect } from "react";
import { createRoot } from "react-dom/client";
const useBeforeLeave = (onBefore) => {
if (typeof onBefore !== "function") {
return;
}
const handle = (event) => {
const { clientY } = event;
if (clientY <= 0) {
onBefore();
}
};
useEffect(() => {
document.addEventListener("mouseleave", handle);
return () => document.removeEventListener("mouseleave", handle);
}, []);
};
const App = () => {
const begForLife = () => console.log("Please don't leave");
useBeforeLeave(begForLife);
return (
<div className="App">
<h1>Hello</h1>
</div>
);
};
const rootElement = document.getElementById("root");
const root = createRoot(rootElement);
root.render(
<StrictMode>
<App />
</StrictMode>
);
useClick
클릭을 감지하는 역할
// component가 mount 되었을 때, eventListener을 추가하고 dependency가 없기에 영원하다.
// 이때 dependency를 넣지않고 없애버린다면 매번 update될 때마다 eventListener가 추가될 것이다.
// 따라서 []를 추가해서 componentDidMount때 단 한번만 실행하라는 의미가 될 것 이고 여기서 나오는 return은 componentWillUnMount일 때 동작하게 된다.
// 즉, function을 리턴받았다면 해당 function은 componentWillUnMount로 부터 호출된 것이다.
import { StrictMode, useEffect, useState, useRef } from "react";
import { createRoot } from "react-dom/client";
const useClick = (onClick) => {
const element = useRef();
useEffect(() => {
if (element.current) {
element.current.addEventListener("click", onClick);
}
return () => {
if (element.current) {
element.current.removeEventListener("click", onClick);
}
};
}, []);
return element;
};
const App = () => {
const sayHello = () => console.log("say hello");
const title = useClick(sayHello);
return (
<div className="App">
<h1 ref={title}> HI </h1>
</div>
);
};
const rootElement = document.getElementById("root");
const root = createRoot(rootElement);
root.render(
<StrictMode>
<App />
</StrictMode>
);
useHover
호버링을 감지하는 역할
// component가 mount 되었을 때, eventListener을 추가하고 dependency가 없기에 영원하다.
// 이때 dependency를 넣지않고 없애버린다면 매번 update될 때마다 eventListener가 추가될 것이다.
// 따라서 []를 추가해서 componentDidMount때 단 한번만 실행하라는 의미가 될 것 이고 여기서 나오는 return은 componentWillUnMount일 때 동작하게 된다.
// 즉, function을 리턴받았다면 해당 function은 componentWillUnMount로 부터 호출된 것이다.
import { StrictMode, useEffect, useState, useRef } from "react";
import { createRoot } from "react-dom/client";
const useHover = (onHover) => {
if (typeof onHover !== "function") {
return;
}
const element = useRef();
useEffect(() => {
if (element.current) {
element.current.addEventListener("mouseenter", onHover);
}
return () => {
if (element.current) {
element.current.removeEventListener("mouseenter", onHover);
}
};
}, []);
return element;
};
const App = () => {
const sayHello = () => console.log("say hello");
const title = useHover(sayHello);
return (
<div className="App">
<h1 ref={title}> HI </h1>
</div>
);
};
const rootElement = document.getElementById("root");
const root = createRoot(rootElement);
root.render(
<StrictMode>
<App />
</StrictMode>
);
useConfirm
확인 혹은 취소를 감지하는 역할
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
const useConfirm = (message = "", onConfirm, onCancel) => {
if (!onConfirm || typeof onConfirm !== "function") {
return;
}
if (!onCancel || typeof onCancel !== "function") {
return;
}
const confirmAction = () => {
if (window.confirm(message)) {
onConfirm();
} else {
onCancel();
}
};
return confirmAction;
};
const App = () => {
const deleteWorld = () => console.log("Deleting the world");
const abort = () => console.log("Aborted");
const confirmDelete = useConfirm("Are you sure?", deleteWorld, abort);
return (
<div className="App">
<button onClick={confirmDelete}>Delete the world</button>
</div>
);
};
const rootElement = document.getElementById("root");
const root = createRoot(rootElement);
root.render(
<StrictMode>
<App />
</StrictMode>
);
useFadeIn
특정 시간 이후 fade-in 효과를 나타냄
import { StrictMode, useEffect, useRef } from "react";
import { createRoot } from "react-dom/client";
const useFadeIn = (duration = 1, delay = 0) => {
if (typeof duration !== "number" || typeof delay !== "number") {
return;
}
const element = useRef();
useEffect(() => {
if (element.current) {
const { current } = element;
current.style.transition = `opacity ${duration}s ease-in-out ${delay}s`;
current.style.opacity = 1;
}
}, []);
return { ref: element, style: { opacity: 0 } };
};
const App = () => {
const fadeInH1 = useFadeIn(1, 2);
const fadeInP1 = useFadeIn(3, 4);
return (
<div className="App">
<h1 {...fadeInH1}>Hello</h1>
<p {...fadeInP1}>hihihi</p>
</div>
);
};
const rootElement = document.getElementById("root");
const root = createRoot(rootElement);
root.render(
<StrictMode>
<App />
</StrictMode>
);
useFullScreen
풀스크린을 감지하는 역할
import { StrictMode, useEffect, useState, useRef } from "react";
import { createRoot } from "react-dom/client";
const useFullScreen = (onFullS) => {
const element = useRef();
const triggerFull = () => {
if (element.current) {
element.current.requestFullscreen();
}
if (onFullS && typeof onFullS === "function") {
onFullS(true);
}
};
const exitFull = () => {
document.exitFullscreen();
if (onFullS && typeof onFullS === "function") {
onFullS(false);
}
};
return { element, triggerFull, exitFull };
};
const App = () => {
const onFullS = (isFull) => {
console.log(isFull ? "We are full" : "We are small");
};
const { element, triggerFull, exitFull } = useFullScreen(onFullS);
return (
<div className="App">
<div ref={element}>
<img src="https://i.ibb.co/R6RwNxx/grape.jpg" />
<button onClick={exitFull}> Exit Full </button>
</div>
<button onClick={triggerFull}> Make Full </button>
</div>
);
};
const rootElement = document.getElementById("root");
const root = createRoot(rootElement);
root.render(
<StrictMode>
<App />
</StrictMode>
);
useNetwork
네트워크 감지 역할
import { StrictMode, useEffect, useState } from "react";
import { createRoot } from "react-dom/client";
const useNetwork = (onChange) => {
const [status, setStatus] = useState(navigator.onLine);
const handleChange = () => {
if (typeof onChange === "function") {
onChange(navigator.onLine);
}
setStatus(navigator.onLine);
};
useEffect(() => {
window.addEventListener("online", handleChange);
window.addEventListener("offline", handleChange);
return () => {
window.removeEventListener("online", handleChange);
window.removeEventListener("offline", handleChange);
};
}, []);
return status;
};
const App = () => {
const handleNetworkChange = (online) => {
console.log(online ? "We just went online" : " We are offline");
};
const status = useNetwork(handleNetworkChange);
return (
<div className="App">
<h1>{status ? "Online" : "Offline"}</h1>
</div>
);
};
const rootElement = document.getElementById("root");
const root = createRoot(rootElement);
root.render(
<StrictMode>
<App />
</StrictMode>
);
반응형
'Basic > React' 카테고리의 다른 글
[React] infinity scroll 무한 스크롤 만들기 (0) | 2023.01.15 |
---|---|
[React] outlet을 이용한 쉬운 레이아웃 교체 (0) | 2023.01.15 |
dashboard design example (0) | 2021.03.24 |
Redux를 이용한 Counter 예제 (0) | 2021.03.24 |
Prittier 저장 시 자동으로 코드 정리하기 (0) | 2021.03.23 |