Javascript/React

실전형 리액트 Hooks 10개 (2) - useEffect, useClick

leeeee.yeon 2021. 7. 30. 22:44
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이 함수가 아닐 때 아무 일도 발생하지 않도록 함