[React] UseState로 즉시 반영이 안되는 문제에 대해서

Mincho·2023년 2월 11일
1

React

목록 보기
3/15
post-thumbnail

🔴 UseState를 이용하여 버튼 클릭시 더해주거나 마이너스해준 값 렌더링해주기

import "./App.css";
import { useState } from "react";

function App() {
  const [data, setData] = useState(0);

  function plusHandler() {
    setData(data + 1);
    console.log("clicked!", data);
  }

  function minusHandler() {
    setData(data - 1);
  }

  return (
    <>
      <div>{data}</div>
      <input type="button" value="+1해주기" onClick={plusHandler} />
      <input type="button" value="-해주기" onClick={minusHandler} />
    </>
  );
}

export default App;

다음과 같이 원하는 값이 렌더링 되지만 console.log에는 변화한 값이 바로 찍히는 것이 아니라 값이 하나씩 밀려서 나오게 된다.



🧐 원인

useState에서 setState로 처리한 값이 바로 반영이 안되었기 때문이다.
=> useState는 비동기처리가 되기때문에 클릭을 했을 때 동기적으로 처리된 데이터를 보여주지 않는다.
=> 결론적으로 리렌더링을 통해 정상적인 값을 표현해주어야 한다.




🤗 해결방법

생각해낸 방법은 두가지이다. useRef방식을 사용하거나 useEffect를 사용하는 방법이다.



👊 useRef를 사용해보기

import "./App.css";
import { useRef, useState } from "react";

function App() {
  // const [data, setData] = useState(0);

  const data = useRef(0);

  function plusHandler() {
    // setData(data + 1);
    data.current = data.current + 1;
    console.log("Plus clicked!", data.current);
  }

  function minusHandler() {
    // setData(data - 1);
    data.current = data.current - 1;
    console.log("Minus clicked!", data.current);
  }

  return (
    <>
      <div>{data.current}</div>
      <input type="button" value="+1해주기" onClick={plusHandler} />
      <input type="button" value="-해주기" onClick={minusHandler} />
    </>
  );
}

export default App;

기존의 useState로 상태관리 하는 것 대신에 useRef로 상태관리를 해주는 방안을 생각해 보았다.

그런데....

...

..

.


위와 같이 변수 값은 변하지만 useRef는 렌더링을 다시 해주지 않아 원하는 값이 화면에 나오지 않는다...


import "./App.css";
import { useRef, useState } from "react";

function App() {
  // const [data, setData] = useState(0);

  const data = useRef(0);
  const [render, setRender] = useState();

  function rendering() {
    setRender([render]);
    console.log("렌더링!!");
  }

  function plusHandler() {
    // setData(data + 1);
    data.current = data.current + 1;
    console.log("Plus clicked!", data.current);
  }

  function minusHandler() {
    // setData(data - 1);
    data.current = data.current - 1;
    console.log("Minus clicked!", data.current);
  }

  return (
    <>
      <div>{data.current}</div>
      <input type="button" value="+1해주기" onClick={plusHandler} />
      <input type="button" value="-해주기" onClick={minusHandler} />
      <input type="button" value="렌더링해주기" onClick={rendering} />
    </>
  );
}

export default App;

그래서 위와 같이 렌더링 해주는 함수를 만들어 강제로 랜더링 해 보았다.

값을 바꿔주고 렌더링하기 버튼을 클릭해주니 문제를 해결할 수 있었다,, 하지만 버튼을 눌렀을 때 값이 바로 console에도 잘 찍히고 화면에도 렌더링해주는 방식이 더 효율적으로 보였다.




👊 UseEffect사용해서 해결하기

import "./App.css";
import { useEffect, useState } from "react";

function App() {
  const [data, setData] = useState(0);

  useEffect(() => {
    console.log(data);
  }, [data]);

  function plusHandler() {
    setData(data + 1);
  }

  function minusHandler() {
    setData(data - 1);
  }

  return (
    <>
      <div>{data}</div>
      <input type="button" value="+1해주기" onClick={plusHandler} />
      <input type="button" value="-해주기" onClick={minusHandler} />
    </>
  );
}

export default App;

 다음과 같이 코드를 바꾸어주었다. useEffect를 추가하여 data에 변화가 있을 때 재렌더링하여 data의 값 변화를 추적해보았다.

😙😙결과적으로 값이 제대로 나오는 것을 확인할 수 있었다!!!



👉 후기

useState를 통해 상태관리를 하는 과정에서 위와같이 즉시반영이 안되는 일이 빈번히 발생할 수 있으므로 react의 상태관리 및 랜더링조건 등을 확실하게 알아야 할 필요가 있어 보인다!!

👍올바른 피드백은 언제든지 환영입니다~!

profile
사진찍는 개발자.

0개의 댓글