실전형 리액트 Hooks 10개 (2) - useEffect, useClick
useEffect
useEffect는 componentWillUnmount, componenDidMount, componentWillUpdate의 기능을 한다.
import React, { useEffect } from "react";
const App = () => {
const sayHello = () => {
console.log('hello');
}
useEffect(() => {
sayHello();
});
return (
<div>
</div>
);
}
export default App;
아무것도 하지 않았는데 console에 hello가 출력된 것을 볼 수 있다.
이를 통해 useEffect가 componenDidMount의 역할을 한다는 것을 알 수 있다.
import React, { useEffect, useState } from "react";
const App = () => {
const sayHello = () => {
console.log('hello');
}
useEffect(() => {
sayHello();
});
const [number, setNumber] = useState(0);
const [num, setNum] = useState(0);
return (
<div>
<button onClick={()=>setNumber(number+1)}>{number}</button>
<button onClick={()=>setNum(num+1)}>{num}</button>
</div>
);
}
export default App;
버튼을 클릭할 때마다 hello가 출력된다.
이를 통해 useEffect가 componenDidUpdate의 역할을 한다는 것을 알 수 있다.
useEffect는 첫 번째 인자로 함수를 받는다.
두 번째 인자로는 dependency를 받는다. deps는 effect가 리스트에 있는 값일 때만 값이 변하도록 활성화한다.
useEffect(sayHello, [number]);
이렇게 하면 number이 바뀔 때(왼쪽 버튼을 클릭할 때)만 hello가 출력된다.
( []일 시, 버튼을 눌러도 hello가 출력되지 않음 )
이를 통해 useEffect가 componentWillUpdate의 역할을 하는 것임을 알 수 있다.
useEffect는 함수가 리턴된다.
이를 통해 useEffect가 componentWillUnmount의 역할을 하는 것임을 알 수 있다.
useTitle
문서의 제목을 업데이트 시켜주는 useTitle이라는 hook을 만들어보자!
원래는 helmet이라는 것을 사용하는데, functional hook 방식으로 만들어보자
import React, { useEffect, useState } from "react";
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...");
return (
<div>
</div>
);
}
export default App;
setTimeout(() => titleUpdater("Home"), 5000);
을 추가하면, 5초 뒤 title이 Home으로 바뀌는 것을 볼 수 있다.
useClick
useClick 훅을 만들며 references에 대해 알아보자.
reference는 기본적으로 우리의 컴포넌트의 어떤 부분을 선택할 수 있는 방법으로, document.getElementByID()와 비슷한 것이다.
import React, { useEffect, useRef, useState } from "react";
const App = () => {
const input = useRef();
setTimeout(()=> console.log(input), 5000);
return (
<div>
<input ref={input} placeholder="text" />
</div>
);
}
export default App;
- input 태그 안에서 ref 속성으로 input 변수를 참조하라고 알려주었다.
콘솔에 input 태그의 정보가 출력된 것을 볼 수 있다.
useClick은 누군가 어떤 element를 클릭했을 때 알려주는 훅이다.
import React, { useEffect, useRef, useState } from "react";
const useClick = (onClick) => {
const element = useRef();
useEffect(() => {
if(element.current){
element.current.addEventListener("click", onClick);
}
});
return element;
}
const App = () => {
const sayHello = () => console.log("hello");
const title = useClick();
return (
<div>
<h1 ref={title}>Halo ~</h1>
</div>
);
}
export default App;
- useClick으로 useRef()를 불러왔고, 레퍼런스를 리턴해주었다
- 그리고 리턴한 값을 h1에게 주었다
- addEventListener - 첫 번째 인자는 이벤트 종류, 두 번째 인자는 함수 이름
Halo ~를 클릭하면 콘솔에 hello가 출력된다.
const useClick = (onClick) => {
if(typeof onClick !== "function"){
return;
}
const element = useRef();
useEffect(() => {
if(element.current){
element.current.addEventListener("click", onClick);
}
return () => {
if(element.current){
element.current.remonveEventListener("click", onClick);
}
}
}, []);
return element;
}
useClick 함수에 조금 변화를 주었다.
- unmount할 때 event listener을 지워주어야 함 > removeEventListener을 리턴해줌
- dependency가 없으므로 업데이트를 고려하지 않는다
- if 문 - componentDidMount, componentDidUpdate 때 호출 ( dependency 존재 시, DidMount 때만 호출 )
- return - componentWillUnmount 때 호출
- onClick이 함수가 아닐 때 아무 일도 발생하지 않도록 함