이론 (Front-end)/React

[React] State 사용하기

이우열 2023. 5. 16. 22:43
728x90

리액트를 사용하여 버튼을 클릭하면 숫자가 증가하는 웹 페이지를 만들어보자.

 

✅ counter 변수와 render 함수 사용

<!DOCTYPE html>
<html>
  <body>
    <div id="root"></div>
  </body>
  <script src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
  <script src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>
  <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
  <script type="text/babel">
    const root = document.getElementById("root");
    let counter = 0;
    function countUp() {
      counter = counter + 1;
      render();
    }
    function render() {
      ReactDOM.render(<Container />, root);
    }
    const Container = () => (
      <div>
        <h3>Total click: {counter}</h3>
        <button onClick={countUp}>Click me</button>
      </div>
    );
    render();
  </script>
</html>

위의 코드를 통해 Container라는 컴포넌트를 만들고 render 함수를 통해 Containerroot 안에 그린다.

Container 안에는 button이 존재하고 이 button을 클릭했을 때 countUp이라는 함수가 실행된다.

countUp let으로 선언된 counter를 하나 증가시키고 다시 render 함수를 불러 화면을 다시 그린다.

 

🚨 문제

여기서 문제는 변하는 무언가가 있을 때마다 render라는 함수를 호출해줘야 변화된 것이 새로 화면에 그려진다.

즉, 모든 변화 끝에는 render 함수를 호출해야 하는 안좋은 코드인 것이다.

 

 

 

✅ React.useState

이를 해결하기 위해 React.useState를 사용한다.

State란 리액트에서 객체이며 변수로 활용된다.

 

<!DOCTYPE html>
<html>
  <body>
    <div id="root"></div>
  </body>
  <script src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
  <script src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>
  <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
  <script type="text/babel">
    const root = document.getElementById("root");
    const Container = () => {
      const data = React.useState(0);
      console.log(data);
      return (
        <div>
          <h3>Total click: 0</h3>
          <button>Click me</button>
        </div>
      );
    };
    ReactDOM.render(<Container />, root);
  </script>
</html>

dataContainer 함수 안에서 React.useState()로 선언한다.

🚨 함수는 중괄호로 묶고 리턴을 해줘야 함에 주의하자.

 

console.logdata를 출력해보면 [0, f]와 같은 형태로 출력된다.

이는 초기값과 값을 변화시킬 수 있는 함수를 나타내는 것이다.

즉, 처음 data를 선언할 때, React.useState(0)과 같이 0이라는 초기값을 주었기 때문에 [0, f]와 같이 출력된다.

만약 초기값이 없을 경우 undefined로 선언된다.

 

 

const root = document.getElementById("root");
function Container() {
  const [counter, setCounter] = React.useState(0);
  const onClick = () => {
    setCounter(counter + 1);
  };
  return (
    <div>
      <h3>Total click: {counter}</h3>
      <button onClick={onClick}>Click me</button>
    </div>
  );
}
ReactDOM.render(<Container />, root);

위에서 사용했던 코드에서 datacounter로 바꿔주고

counter를 변화시킬 수 있는 setCounter 함수를 React.useState 함수에 선언해준다.

그리고 버튼을 클릭하면 실행되는 onClick 함수를 선언한다.

onClick 함수는 counter의 값을 변화시킬 수 있는 setCounter 함수를 호출한다.

setCounter 함수는 counter를 1 증가시키고 화면을 리렌더링한다.

 

🚨 주의!

setCounter 함수 안에서 1을 증가시키기 위해 counter++를 사용하면 안된다.

이유는 전위 연산자, 후위 연산자의 차이에서 나타난다.

 

전위 연산자는 ++counter, 후위 연산자는 counter++로 사용하는데

후위 연산자의 경우 할당 후 counter를 증가시킨다.

 

그렇기 때문에 렌더링 과정에서 할당이 되고 난 뒤 counter가 증가해 원하는 결과를 얻을 수 없다.

만약 사용하려면 ++counter와 같은 전위 연산자를 사용하도록 하자.

 

 

 

✅ State를 세팅하는 방법

1. 직접 값을 설정

const [counter, setCounter] = React.useState(0);
const onClick = () => {
  setCounter(counter + 1);   // (a)
  // setCounter(987);        // (b)
  // setCounter("lalalal");  // (c)
};

(a) counter라는 변수에 1을 더해서 직접 값을 설정하는 방법

(b) 987이라는 값을 설정하는 방법

(c) 숫자가 아닌 문자열로 바꿔서 설정하는 방법

 

 

 

2. 함수 전달

const [counter, setCounter] = React.useState(0);
const onClick = () => {
  setCounter((current) => current + 1);
};

함수를 통해서 state를 설정

current라는 인자에 1을 더해서 반환(return)하면 언제나 현재 state를 얻어서 변화를 줄 수 있음

 

 

 

🚨 함수 전달을 사용해야 하는 이유

const [counter, setCounter] = React.useState(0);
const onClick = () => {
  setCounter(counter + 1);
  setCounter(counter + 1);
  setCounter(counter + 1);
};
const [counter, setCounter] = React.useState(0);
const onClick = () => {
  setCounter((current) => current + 1);
  setCounter((current) => current + 1);
  setCounter((current) => current + 1);
};

두가지의 경우를 출력해서 사용해보면 이해가 쉽다.

 

 

✏️ 첫 번째의 경우

counter에 1을 증가시켜 counter를 설정하는 방식이다.

counter가 0으로 설정되어 있고 버튼을 클릭하여 onClick 함수를 실행시켰다면

첫 번째 setCounter 함수에서 counter인 0에 1을 더하여 counter에 할당한다.

두 번째, 세 번째 setCounter 함수도 마찬가지로 실행 당시의 counter 값인 0에 1을 더해 counter에 할당한다.

결국 counter는 마지막에 할당한 1이 되고 함수가 종료된다.

 

✏️ 두 번째의 경우

current라는 인자에 1을 더해 반환하는데 항상 현재의 값을 찾아 1을 더한다.

즉, 첫 번째 setCounter 함수에서 현재 counter 값인 0에 1을 더해 1을 할당하고

두 번째 setCounter 함수에서 현재 counter 값인 1에 1을 더해 2가 할당된다.

마지막으로 2에 1을 더해 3으로 할당해 함수가 종료된다.

 

✏️ 정리

단순 counter + 1과 같은 형태로 사용한다면 함수를 몇 번 호출하더라도 마지막에 할당된 값이 counter에 영향을 준다.

하지만 현재의 값을 가져와 함수 형태로 리턴해준다면 모든 함수가 변수에 영향을 줄 수 있다.

728x90