Early Riser
생각정리
Early Riser
전체 방문자
오늘
어제
  • 분류 전체보기 (128)
    • JS (19)
    • React (33)
    • React Native (2)
    • Library, Tool (13)
    • CSS (2)
    • Algorithm (40)
    • Computer Science (3)
    • 회고 (3)
    • AI (13)

블로그 메뉴

  • 홈
  • 태그
  • 방명록
  • 글쓰기

공지사항

인기 글

태그

  • useState
  • 딥러닝
  • useEffect
  • 부스트캠프 9기
  • 백트래킹
  • 자바스크립트
  • RNN
  • 완전탐색
  • 논문리뷰
  • 비동기
  • global minima
  • boosting
  • 부스트캠프 합격
  • javascript
  • 프로그래머스
  • 파이썬
  • BFS
  • react
  • js
  • 밑바닥
  • 손실함수
  • 구현
  • 부스트캠프 합격 후기
  • 백준
  • lightgbm
  • LGBM
  • local minima
  • dfs
  • 오늘의불경
  • 알고리즘

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
Early Riser

생각정리

React

React Hook을 사용할 때 실수들 (1): useState

2024. 9. 10. 12:21

서론

 React에서 상태 관리를 위해 useState는 매우 자주 사용되는 훅이다. 하지만 이 훅들을 잘못 사용하면 예기치 않은 동작이나 성능 문제를 일으킬 수 있다. 이 글에서는 useState를 사용할 때 흔히 저지르는 실수들과 그 해결 방법을 다룰 것이다.

1. setState는 즉시 실행되지 않는다

 useState로 상태를 업데이트할 때 흔히 착각하는 부분은 setState가 즉시 상태를 업데이트한다고 생각하는 것이다. 하지만 React는 여러 상태 업데이트 요청을 모아서 한 번에 처리하는 특성을 갖고 있다. 아래 예제 코드를 보자.

import React, { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0);

  // ❌ 두 번 증가시키고 싶지만 실제로는 한 번만 증가함
  const incrementTwice = () => {
    setCount(count + 1);
    setCount(count + 1); 
  };

  // ✅ 두 번 증가함
  const incrementTwice = () => {
    setCount((prevCount) => prevCount + 1);
    setCount((prevCount) => prevCount + 1); 
  };

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={incrementTwice}>Increase Twice</button>
    </div>
  );
}

 위 예시에서 두 번 setCount를 호출해도 count는 한 번만 증가한다. 이는 React가 상태 업데이트를 비동기적으로 처리하고, 최종적으로 한 번의 렌더링으로 묶기 때문이다. 이를 해결하려면 setState에 콜백 함수를 전달해야 한다.

2. 객체 상태를 업데이트할 때는 spread 연산자를 사용하라

 리액트에서는 객체 상태를 업데이트할 때 불변성 때문에 새로운 객체를 생성한다. 따라서 객체의 값을 업데이트 해야할때는 spread 연산자를 사용하는 것이 좋다.

import React, { useState } from 'react';

function Example() {
  const [data, setData] = useState({ a: 1, b: 2 });

  // ❌ 기존 값을 덮어쓰기 때문에 b는 사라지고 a만 3으로 업데이트됨
  const updateDataWrong = () => {
    setData({ a: 3 });
  };

  // ✅ 기존 b는 유지하면서 a만 변경
  const updateDataCorrect = () => {
    setData((prevData) => ({ ...prevData, a: 3 }));
  };

  return (
    <div>
      <button onClick={updateDataWrong}>Update (Wrong)</button>
      <button onClick={updateDataCorrect}>Update (Correct)</button>
      <p>{data.a}</p>
      <p>{data.b}</p>
    </div>
  );
}

3. useState 여러 개 대신 객체를 활용하라

 여러 개의 useState를 사용하는 대신 하나의 객체를 상태로 관리할 수 있다. 이 방법은 상태가 서로 관련이 있을 때 유용하다.

import React, { useState } from 'react';

function Form() {
  const [formData, setFormData] = useState({ name: '', age: '' });

  const handleChange = (e) => {
    const { name, value } = e.target;
    setFormData((prev) => ({ ...prev, [name]: value }));
  };

  return (
    <div>
      <input name="name" value={formData.name} onChange={handleChange} />
      <input name="age" value={formData.age} onChange={handleChange} />
    </div>
  );
}

4. 상태나 props로부터 계산된 값을 새로운 상태로 만들 필요는 없다

 예를 들어, total이라는 상태를 갖고 있고, 이 상태로부터 price를 계산한다고 가정하자. 새로 상태를 만들어서 관리하는 대신, 기존 상태로부터 계산된 값을 사용하는 것이 더 효율적이다.

import React, { useState } from 'react'; 

function Example() { 
    const [total, setTotal] = useState(100); 
    const price = total * 5; // 새로 상태를 만들 필요 없음 
    return ( 
        <div> 
            <p>Total: {total}</p> 
            <p>Price: {price}</p> 
        </div> 
    ); 
}

 total이 변경될 때마다 컴포넌트는 재렌더링되므로 price는 total의 변경된 값을 기준으로 다시 계산된다. 따라서 price도 자동으로 업데이트되므로, 불필요한 상태 업데이트를 줄일 수 있다.

Reference

https://react.dev/learn/you-might-not-need-an-effect

https://react.dev/reference/react/useEffect#fetching-data-with-effects

https://www.youtube.com/watch?v=-yIsQPp31L0

'React' 카테고리의 다른 글

컴포넌트 구성은 훌룡합니다 그런데  (3) 2024.09.26
React Hook을 사용할 때 실수들 (2): useEffect  (2) 2024.09.10
React Hook 이해하기 (4): useMemo, useCallback  (0) 2024.09.10
React Hook 이해하기 (3): useRef  (0) 2024.09.10
React Hook 이해하기 (2): useEffect  (0) 2024.09.10
    'React' 카테고리의 다른 글
    • 컴포넌트 구성은 훌룡합니다 그런데
    • React Hook을 사용할 때 실수들 (2): useEffect
    • React Hook 이해하기 (4): useMemo, useCallback
    • React Hook 이해하기 (3): useRef
    Early Riser
    Early Riser
    2년차 프론트엔드 개발자입니다. https://github.com/EarlyRiser42

    티스토리툴바