useEffect를 활용한 hook를 설계하기전에 useEffect이 무엇인지 알아보자. useEffect는 변화를 감지하여 등록된 함수를 실행하는 기능이다.
import React, { useState, useEffect } from "react";
export default function App() {
const [number, setNumber] = useState(0);
const [aNumber, setAnumber] = useState(0);
const sayHello = () => console.log("hello");
useEffect(() => {
sayHello();
}, [number]);
return (
<div className="App">
<div>Hi</div>
<button onClick={() => setNumber(number + 1)}>{number}</button>
<button onClick={() => setAnumber(aNumber + 1)}>{aNumber}</button>
</div>
);
}
useEffect가 생기기 이전에 class component에는 다양한 component함수들이 있었다.
그리고 이 함수들은 useEffect hook으로 대체되었고 useEffect에 제공되는 인자에 따라 동작을한다.
useEffect는 두번째 인자는 변수를 등록하여 변수값에 변화가 있을때 useEffect를 동작시킨다.
useEffect는 첫번째 인자는 useEffect가 동작할때 실행되는 함수이다.
위 코드를 해석하면 useEffect에 sayHello함수가 등록되고 number변수가 값이 변화할때마다 sayHello가 호출된다. 그리고 이런 useEffect를 활용한 hook을 디자인 해본다.
useTitle은 useEffect를 활용하여 페이지의 타이틀을 손쉽게 변환해주는 기능이다.
import React, { useState, useEffect } from "react";
import ReactDom from "react-dom";
const useTitle = (initialTitle) => {
const [title, setTitle] = useState(initialTitle);
const updateTitle = () => {
const htmlTitle = document.querySelector("title");
htmlTitle.innerText = title;
};
useEffect(updateTitle, [title]);
return setTitle;
};
export default function App() {
const setTitle = useTitle("Loading...");
setTimeout(() => setTitle("Home"), 5000);
return (
<div className="App">
<div>Hi</div>
</div>
);
}
App component에서 useTitle이 호출되면 useState에 title state가 구독되고 아래 useEffec가 updateTitle(componentDidUpdate)를 호출한다. 그럼 updateTitle은 dom에 있는 title tag값을 title state값으로 변경하는 작업을 하고 useTitle는 setTitle을 반환한다.
이후 반환된 setTitle이 App component에서 실행되면 tite state가 변경되고 변경을 감지한 useEffect가 updateTitle를 호출하여 title tag값을 변경한다.
위 코드는 매우 심플하면서 간편한 hook을 설계한거다. 이뿐만아니라 useEffect만으로 다양한 hook설계를 진행한다.