Note

React State 본문

Dev/React

React State

레모네모 2019. 12. 15. 16:04

1. 개요

state는 컴포넌트의 내부에서 컴포넌트의 상태를 저장하는 값입니다.

props는 부모에서 전달해서 읽기전용으로 사용하는 변수라면 state는 컴포넌트 내부에서 읽기 뿐만 아니라 수정을 할 수 있습니다.

 

2. 초기화

컴포넌트에서 state를 초기화 하는 방법은 2가지가 있습니다.

첫 번째는 필드(?)에서 선언하는 방법이고, 두 번째는 생성자(constructor)에서 선언하는 방법입니다.

import React from "react";

class StateCheckClassComponent extends React.Component {
  state = {
    checked: false
  };
  
  render() {
    return (
      <React.Fragment>
        <label><input type="checkbox" />checkbox</label>
      </React.Fragment>
    )
  }
}

export default StateCheckClassComponent;
import React from "react";

class StateCheckClassComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      checked: false
    };
  }
  
  render() {
    return (
      <React.Fragment>
        <label><input type="checkbox" />checkbox</label>
      </React.Fragment>
    )
  }
}

export default StateCheckClassComponent;

둘 중 어떤 방법을 사용할 지는 사용하는 사람의 취향이지만 개인적으로는 1번방법을 선호하고 있습니다.

3. 조회

조회를 하는 것은 그냥 state에서 값을 빼서 사용을 하면 됩니다.

import React from "react";

class StateCheckClassComponent extends React.Component {
  state = {
    checked: false
  };

  render() {
    const {checked} = this.state;
    return (
      <React.Fragment>
        <label><input type="checkbox" checked={checked} />checkbox</label>
      </React.Fragment>
    )
  }
}

export default StateCheckClassComponent;

4. 수정

수정을 하는 방법은 3가지가 있습니다.

첫 번째와 두 번째는 setState를 사용하는 것이고 세 번째는 useState를 사용하는 것입니다.

state를 사용할 때 this.state.checked = false;와 같이 사용하는 것은 잘 못된 방법입니다.

import React from "react";

class StateCheckClassComponent extends React.Component {
  state = {
    checked: false
  };

  handleChange = () => {
    const {checked} = this.state;
    this.setState({
      checked: !checked
    });
  };

  render() {
    const {checked} = this.state;
    return (
      <React.Fragment>
        <label><input type="checkbox" checked={checked} onChange={this.handleChange} />checkbox</label>
      </React.Fragment>
    )
  }
}

export default StateCheckClassComponent;

위의 코드와 같이 setState 함수를 통해 state의 값을 바꿀 수 있습니다.

그런데 만약 위의 handleChange 함수가 아래와 같이 바뀐다고하면 어떻게 될까요?

handleChange = () => {
  const {checked} = this.state;
  this.setState({
    checked: !checked
  });

  this.setState({
    checked: !this.state.checked
  });
};

값을 두 번 바꿨기 때문에 원래의 값으로 유지될 것 같지만, React는 State의 값을 비동기로 업데이트 하기 때문에 state에 값이 바로 반영되지 않고, 원래 state의 반대값이 저장되게 됩니다.

비동기로 처리되는 값을 순서대로 동기로 처리해야되는 일이 있다면 아래와 같은 방법으로 하면 됩니다.

handleChange = () => {
  this.setState({
    checked: !this.state.checked
  });
  this.setState((prevState, props) => {
    console.log(prevState);
    return {
      checked: prevState.checked
    }
  })
};

동기로 처리해야 되는 부분에서 setState에 객체가 아닌 함수를 전달하고, 함수에서 이전 상태(prevState)를 받아서 바뀐 값으로 처리를 할 수 있습니다.

그리고 변경되는 상태를 객체로 반환하게 되면 상태가 바뀌게 됩니다.

setState 함수는 두 번째 인자로 함수를 전달하면, state 값이 바뀐 후 두 번째 인자의 함수를 callback으로 실행시켜서 callback함수에서 처리를 하는 방법도 있습니다.

handleChange = () => {
  this.setState({
    checked: !this.state.checked
  }, () => {
    console.log('callback!!!!!!!', this.state.checked);
  });
};

세 번째 방법은 함수형 컴포넌트에서도 state를 사용할 수 있도록 해주는 방법인데요, Hooks라는 것을 사용하는 방법입니다.

Hooks에 대해서는 나중에 더 자세히 다루도록 하고, useState를 사용하는 방법은 아래와 같습니다.

import React, {useState} from "react";

const StateCheckFunctionalComponent = (props) => {
  const [checked, setChecked] = useState(false);

  const handleChange = () => {
    setChecked(!checked);
  };

  return (
    <React.Fragment>
      <label><input type="checkbox" checked={checked} onChange={handleChange} />checkbox</label>
    </React.Fragment>
  );
};

export default StateCheckFunctionalComponent;

useState 함수에 state의 기본 값을 전달하면 useState함수는 state 값과 이를 수정할 수 있는 함수를 반환하게 됩니다.

이 반환된 함수와 값으로 상태를 사용하고, 상태의 값을 수정할 수 있습니다.

'Dev > React' 카테고리의 다른 글

React Lifecycle  (0) 2019.12.15
React Events  (0) 2019.12.15
React Prop  (0) 2019.12.08
React Component  (0) 2019.12.08
React 시작하기  (0) 2019.12.08
Comments