React Hooks (1) - useState, useEffect, useRef

G_NooN·2024년 1월 31일
0

React

목록 보기
10/14

useState

가변적인 상태를 가지는 state 변수를 선언하는 Hook

형태

일반적으로 구조 분해 할당을 사용하여 표현함

  import { useState } from "react";
  
  const [변수명, set변수명] = useState(초기값);
  // 변수명 : 현재 state
  // set변수명 : 현재 state를 다른 값으로 업데이트하고 리렌더링 할 수 있는 set 함수

state의 set 방법

1. 일반적 방법

  • setState() 안에 수정할 값을 입력한다.
  setState(number + 1);

2. 함수형 방법

  • setState() 안에 함수를 넣는다.
    • 입력값 : 현재 state / 출력값 : state를 변경하는 작업
  setState(number => number + 1);

차이점

동일한 set 함수를 여러 번 수행했을 때의 결과가 다르다.

  const [number, setNumber] = useState(0);
  // 일반 업데이트
  <button onClick={() => {
    setNumber(number + 1);
    setNumber(number + 1);
    setNumber(number + 1);
  }}>일반 +3</button>

  // 함수형 업데이트
  <button onClick={() => {
    setNumber((number) => number + 1);
    setNumber((number) => number + 1);
    setNumber((number) => number + 1);
  }}>함수형 +3</button>

  // 최종 결과: 일반(0 -> 1) vs 함수형(0 -> 3)

이유

  1. React는 렌더링의 횟수에 따라 성능이 좌우된다.

  2. 따라서, React는 성능을 최적화하기 위해 자체적으로 이벤트 핸들러의 모든 코드가 실행된 이후에 state를 업데이트한다.

  3. 따라서, 이벤트 핸들러가 완전히 실행될 때까지 핸들러 내부의 state 값은 이전 state 값으로 고정되어 있다.

  4. 일반 업데이트는 계속해서 기존에 고정된 number에 단순히 1만 추가하라는 행위만 반복하고 있다.

  5. 반면, 함수형 업데이트는 함수들을 큐(queue) 에 넣어 수행하기 때문에, 이전 함수의 결과값을 다음 함수의 입력값으로 사용할 수 있다.


useEffect

React 컴포넌트가 (리)렌더링될 때마다 특정 작업을 수행하는 Hook

형태

  import { useEffect } from "react";

  useEffect(수행할 함수, 의존성 배열)

의존성 배열

(리)렌더링될 때마다 특정 작업을 수행하게 할 컴포넌트를 bind한다.

  import { useEffect, useState } from "react";

  function App() {
    const [value, setValue] = useState("");
    
    const valueChangeHandler = (event) => {
      setValue(event.target.value);
    };
    
    useEffect(() => {
      console.log("해당 컴포넌트이 (리)렌더링 될 때만 반응함");
    }, [value]);	// value가 (리)렌더링 될 때만 반응함
    
    return <input type="text" value={value} onChange={valueChangeHandler} />;
  }  

빈 배열([])을 입력할 경우, 처음 렌더링된 이후 어떠한 렌더링에도 수행되지 않는다.

  useEffect(() => {
    console.log("첫 렌더링 이후 어떠한 (리)렌더링에도 반응하지 않음");
  }, []);

Clean Up

컴포넌트가 DOM에서 제거되기 직전에 실행되는 작업

사용법

useEffect()의 함수 내부에 return문을 사용하고 그 안에 실행할 작업을 작성한다.

  useEffect(() => {
    console.log("value 컴포넌트가 (리)렌더링될 때마다 수행함");
    
    return () => {
      console.log("value 컴포넌트가 DOM에서 제거되었습니다.");
    };
  }, [value]);

useRef

렌더링에 관여하지 않는 값을 참조하는 Hook

형태

  import { useRef } from "react";

  const 변수명 = useRef(초기값);
  // 초기값 : 첫 렌더링에만 적용되며, 이후 해당 값을 변경하는 경우, 변경한 값이 적용됨

특징

  • current 속성을 가진 객체다. ref = {current: 초기값}
  • current 값이 수정되어도 렌더링에는 반영되지 않는다.

사용법

주로 DOM 요소를 선택할 때 사용함

  • ref 변수를 초기화하고, ref 적용할 DOM 요소에 ref 속성을 입력함
  function App() {
    const valueRef = useRef("");
    
    return <input type="text" ref={valueRef} />
  }

useState vs useRef

기본 개념
useState : 렌더링에 반영되는 값에 사용한다.
useRef : 렌더링에 반영되지 않는 값에 사용한다.

두 Hook과 <input>과의 관계

코드

출력 결과

  • useState
    • input에 값을 입력하면, 해당 값이 변경될 때마다 그 변화를 화면에 리렌더링하기 때문에, 사용자가 값의 변화를 직접 눈으로 볼 수 있다.
    • 따라서, 검색창과 같은 입력 컴포넌트에 적합하다고 생각한다.
  • useRef
    • input에 값을 입력하면, 해당 값이 내부적으로는 반영되지만, 그 변화가 화면에 출력되지는 않는다.
    • 따라서, 개인 정보와 관련된 입력 컴포넌트에 적합하다고 생각한다.

<input>에 어떤 Hook을 쓰는 것이 더 효율적인가?

나는 useState를 사용하는 것이 더 효율적이라고 생각한다.

<input> 으로 접근했을 때 가장 먼저 생각난 것은 검색창 이었다.

검색창은 <input> 창에 글자를 입력할 때마다 일치하는 연관 검색어를 추천해준다.

해당 컴포넌트에는 useState를 사용하는 것이 적합하다.

useRef를 사용해서도 검색 기능을 수행할 수는 있지만, 화면에 보여지지 않고 내부적으로 검색어를 파악한 뒤 검색 결과를 출력해야 하며, 이는 UX 적인 부분에서 useState 보다 좋지 않다고 생각한다.

profile
쥐눈(Jin Hoon)

0개의 댓글