import React, { useState, useEffect } from "react";
import "./styles.css";
const useTitle = initialTitle => {
const [title, setTitle] = useState(initialTitle);
const update = () => {
const html = document.querySelector("title");
html.innerText = title;
};
useEffect(update, [title]);
return setTitle;
};
const App = () => {
const titleUpdate = useTitle("Loading...");
setTimeout(() => titleUpdate("home"), 5000);
return <div className="App">hi</div>;
};
export default App;
useEffect( ... ,[ a ] )
란,a
값이 바뀔 때만 useEffect가 재실행 된다는 것.
5초 후에 titleUpdate("home") 로 인해 title 상태 값이 Loading... 에서 home으로 바뀐다.
title값이 바뀌면서 useEffect에 있는 update 함수가 재실행된다.
5초 뒤에 < title > 텍스트 값이 Loading... 에서 home으로 바뀌는걸 볼 수 있다.
useRef() 로 생성할 수 있고 .current 속성으로 접근 가능하다.
(단, useRef 는 리렌더링을 발생시키지 않는다.)
import React, { useRef } from "react";
import "./styles.css";
const App = () => {
const potato = useRef();
setTimeout(() => console.log(potato.current), 5000);
return (
<div className="App">
<input ref={potato} placeholder="la" />
</div>
);
};
export default App;
위 코드에서는 5초 뒤에 potato가 참조
하고 있는
< input placeholder="la" > 가 콘솔로 출력된다.
import React, { useState } from "react";
import "./styles.css";
const content = [
{
tab: "Section 1",
content: "Hi"
},
{
tab: "Section 2",
content: "Hi 2"
}
];
const useTabs = (initialTab, allTabs) => {
if (!allTabs || !Array.isArray(allTabs)) {
return;
}
const [currentIndex, setCurrentIndex] = useState(initialTab);
return {
currentItem: allTabs[currentIndex],
changeItem: setCurrentIndex
};
};
const App = () => {
const { currentItem, changeItem } = useTabs(0, content);
return (
<div className="App">
{content.map((section, index) => (
<button onClick={() => changeItem(index)}>{section.tab}</button>
))}
<div>{currentItem.content}</div>
</div>
);
};
export default App;
import React from "react";
import "./styles.css";
const useConfirm = (message = "", callback) => {
if (typeof callback !== "function") {
return;
}
const confirmAction = () => {
if (confirm(message)) callback();
};
return confirmAction;
};
const App = () => {
const deleteWorld = () => {
console.log("deleting the world");
};
const confirmDelete = useConfirm("Are you sure", deleteWorld);
return (
<div className="App">
<button onClick={confirmDelete}>Delete</button>
</div>
);
};
export default App;
버튼을 누른 뒤 "Are you sure?" 이라는 confirm 창이 뜨고, yes를 누르면 callback 인자로 들어간 deleteWorld 함수가 실행되어 "deleting the world" 라는 콘솔이 뜬다.
import React, { useEffect } from "react";
import "./styles.css";
const useBeforeLeave = onBefore => {
if (typeof onBefore !== "function") {
return;
}
const handle = () => {
onBefore();
};
useEffect(() => {
document.addEventListener("mouseleave", handle);
return () => document.removeEventListener("mouseleave", handle);
}, []);
};
const App = () => {
const beg = () => console.log("plz don't leave");
useBeforeLeave(beg);
return <div className="App">hi</div>;
};
export default App;
useEffect 안의
return () => document.removeEventListener("mouseleave", handle);
는componentWillUnMount
일땐 mouseleave 이벤트를 지우겠다는 의미
마우스가 화면을 벗어나면 mouseleave 이벤트가 발생해서 handle이 실행되고 이로인해 onBefore인자로 들어온 beg 함수가 실행되어 "plz don't leave" 라는 문장이 콘솔에 출력된다.
import React, { useRef, useEffect } from "react";
import "./styles.css";
const useFadeIn = (duration = 1, delay = 1) => {
if (typeof duration !== "number" || typeof delay !== "number") {
return;
}
const element = useRef();
useEffect(() => {
if (element.current) {
element.current.style.transition = `opacity ${duration}s ease-in-out ${delay}s`;
element.current.style.opacity = 1;
}
}, []);
return { ref: element, style: { opacity: 0 } };
};
const App = () => {
const fadeInH1 = useFadeIn(1, 2);
const fadeInP = useFadeIn(10, 5);
return (
<div className="App">
<h1 {...fadeInH1}>h1</h1>
<p {...fadeInP}>pp</p>
</div>
);
};
export default App;
h1은 2초 뒤에 1초 동안 서서히 나타나고, pp는 5초 뒤에 10초 동안 서서히 나타난다.
import React, { useState, useEffect } from "react";
import "./styles.css";
const useScroll = () => {
const [state, setState] = useState({ x: 0, y: 0 });
const onScroll = () => {
setState({ x: window.scrollX, y: window.scrollY });
};
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>
);
};
export default App;
처음 초기값(0, 0) 으로 파란색인 hi가 스크롤을 내리면 y 상태 값이 100을 넘어 hi가 빨간색이 된다.
( div에 1000vh 높이를 지정해준 이유는 스크롤을 만들기 위해서이다. )