FRONT-END/REACTJS

state

JINGMONG 2021. 12. 19. 03:38

리액트에서 state는 컴포넌트 내부에서 바뀔 수 있는 값을 의미한다. props는 컴포넌트가 사용되는 과정에서 부모 컴포넌트가 설정하는 값이며, 컴포넌트 자신은 해당 props를 읽기 전용으로만 사용할 수 있다. props를 바꾸려면 부모 컴포넌트에서 바꿔줘야한다.

클래스형 컴포넌트의 state

Counter.js

import React, { Component } from 'react';

class Counter extends Component {
  constructor(props) {
    super(props);
    this.state = {
      number: 0,
    };
  }
  render() {
    const { number } = this.state; // state를 조회할 때는 this.state로 조회
    return (
      <div>
        <h1>{number}</h1>
        {/* this.setState를 사용하여 state에 새로운 값을 넣을 수 있다.*/}
        <button onClick={() => this.setState({ number: number + 1 })}>
          +1
        </button>
      </div>
    );
  }
}

export default Counter;

컴포넌트에서 state를 설정할 때는 constuctor 메서드를 작성해야 한다.

  constructor(props) {
    super(props);
    this.state = {
      number: 0,
    };
  }

이는 컴포넌트의 생성자 메서드이다. 클래스형 컴포넌트에서 constuctor를 작성할 때는 반듯이 super(props)를 호출해 주어야 한다. 이 함수가 호출되면 현재 클래스형 컴포넌트가 상속하고 있는 리액트의 Component 클래스가 지닌 생성자 함수를 호출해 준다.

다음에는 this.state 값에 초깃값을 설정해 준다.

App.js

import { Component } from 'react';
import Counter from './Counter';

class App extends Component {
  render() {
    return (
      <Counter />
    );
  }
}

export default App;

state의 초깃값을 constuctor 메서드 선언없이 설정하기

import React, { Component } from 'react';

class Counter extends Component {
  state = {
    number: 0,
  };
  render() {
    const { number } = this.state;
    return (
      <div>
        <h1>{number}</h1>
        <button onClick={() => this.setState({ number: number + 1 })}>
          +1
        </button>
      </div>
    );
  }
}

export default Counter;

this.setState에 함수 인자 전달

onClick={() => {
  this.setState({ number: number + 1 });
  this.setState({ number: this.state.number + 1 });
}}

처럼 작성하면 this.setState를 두 번 사용했지만 버튼을 클릭했을 때 숫자가 1만 더해진다.

setState는 비동기적으로 업데이트 되기 때문에 setState가 두번 호출되었다고 해서 값이 바로 바뀌지 않는다.

이를 해결하기 위하여 this.setState를 사용할 때 객체 대신 함수를 인자로 넣어 사용한다

this.setState((prevState, props) => {
  return {
    ...
  }
})

Counter.js

import React, { Component } from 'react';

class Counter extends Component {
  state = {
    number: 0,
  };
  render() {
    const { number } = this.state;
    return (
      <div>
        <h1>{number}</h1>
        <button
          onClick={() => {
            this.setState((prevState) => {
              return {
                number: prevState.number + 1,
              };
            });
            this.setState((prevState) => ({
              number: prevState.number + 1,
            }));
          }}
        >
          +1
        </button>
      </div>
    );
  }
}

export default Counter;

this.setState 후 특정 작업 실행

setState를 사용하여 값을 업데이트한 후 특정 작업을 하고 싶다면 setState의 두 번째 파라미터로 콜백 함수를 등록하여 처리할 수 있다.

onClick={() => {
  this.setState(
    (prevState) => ({
      number: prevState.number + 1,
    }),
    () => {
      console.log('setState>>>' + this.state.number);
    }
  );
}}

함수 컴포넌트에서 useState 사용

리액트 v16.8 이전에는 함수 컴포넌트에서 state를 사용할 수 없었다. 이후 useState를 사용하여 함수 컴포넌트에서도 state를 사용할 수 있게 되었다.

useState

import React, { useState } from 'react';

const Login = () => {
  const [message, setMessage] = useState('');
  const onClickLogin = () => setMessage('로그인 되었습니다.');
  const onClickLogout = () => setMessage('로그아웃 되었습니다.');
  return (
    <div>
      <button onClick={onClickLogin}>로그인</button>
      <button onClick={onClickLogout}>로그아웃</button>
      <h1>{message}</h1>
    </div>
  );
};

export default Login;

useState 여러번 사용

import React, { useState } from 'react';

const Login = () => {
  const [message, setMessage] = useState('');
  const onClickLogin = () => setMessage('로그인 되었습니다.');
  const onClickLogout = () => setMessage('로그아웃 되었습니다.');

  const [color, setColor] = useState('black');

  return (
    <div>
      <button onClick={onClickLogin}>로그인</button>
      <button onClick={onClickLogout}>로그아웃</button>

      <h1 style={{ color }}>{message}</h1>

      <button style={{ color: 'red' }} onClick={() => setColor('red')}>
        빨간색
      </button>
      <button style={{ color: 'green' }} onClick={() => setColor('green')}>
        초록색
      </button>
      <button style={{ color: 'blue' }} onClick={() => setColor('blue')}>
        파란색
      </button>
    </div>
  );
};

export default Login;

state 주의 사항

state값을 바꾸어야 할 때는 setState 또는 useState를 통해 전달받은 세터 함수를 사용해야 한다.

배열이나 객체를 업데이트 할 때는 배열이나 객체를 복사한 후 그 값을 변경하고 세터 함수를 통해 업데이트 해야한다.

'FRONT-END > REACTJS' 카테고리의 다른 글

ref를 사용하는 상황  (0) 2021.12.24
이벤트 핸들링  (0) 2021.12.20
props  (0) 2021.12.19
컴포넌트  (0) 2021.12.19
JSX 문법  (0) 2021.12.18