(React) State

기완·2021년 6월 3일
0

React basic

목록 보기
4/8
post-thumbnail

State

  • 단어 뜻 그대로 컴포넌트 내부에서 가지고 있는 컴포넌트의 상태값입니다.
  • state는 화면에 보여줄 컴포넌트의 UI 정보(상태)를 지니고 있는 객체입니다.
  • state는 컴포넌트 내에서 정의하고 사용하며 얼마든지 데이터(객체)가 변경될 수 있습니다.(👌동적인 데이터)
import React from 'react';
class State extends React.Component {
  constructor() {
    super();
    this.state = {
      color: 'red'
    };
  }
render() {
    return (
      <div>
        <h1>Class Component | State</h1>
      </div>
    );
  }
}
export default State;
  • 클래스형 컴포넌트 안에는 필수적으로 render 함수가 필요하고 화면에 나타내고 싶은 JSX 요소가 return문 안에 들어있습니다.
  • render 함수 위에 constructor 함수를 보도록 하겠습니다.
  • state를 설정할 때는 화면에 보이듯이 constructor 함수를 작성하여 설정합니다.
  • constructor 함수는 컴포넌트 선언문(class State extends Component)과 render 함수 사이에 작성합니다.

    constructor에서 super(props) 를 호출 한 이유는, 컴포넌트를 만들게 되면서, Component를 상속했으며, 이렇게 constructor를 작성하게 되면 기존의 클래스 생성자를 덮어쓰게 됩니다. 그렇기에, 리액트 컴포넌트가 지니고있던 생성자를 super 를 통하여 미리 실행하고, 그 다음에 우리가 할 작업 (state 설정) 을 해주는 것 입니다

import React, { Component } from 'react';

class Counter extends Component {
  state = {  //객체형으로 정의
    number: 0
  }

class fields 문법을 사용해서 이렇게 간단히 쓰는 방법도 있습니다.

👉메소드 작성

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

  handleDecrease = () => {
    this.setState({
      number: this.state.number - 1
    });
  }

👉setState
state 에 있는 값을 바꾸기 위해서는, this.setState 를 무조건 거쳐야합니다.
리액트에서는, 이 함수가 호출되면 컴포넌트가 리렌더링 되도록 설계되어있습니다.
setState는, 객체로 전달되는 값만 업데이트를 해줍니다.
지금은 state 에 number값 밖에 없지만 만약에 다음과 같이 다른 값이 있다고 가정해봅시다.

 state = {
    number: 0,
    foo: 'bar'
  }

그러면, this.setState({ number: 1 }); 을 하게 된다면, foo 는 그대로 남고, number 값만 업데이트 됩니다.
setState 는 객체의 깊숙한곳 까지 확인하지 못합니다. 예를들어서, state 가 다음과 같이 설정되어있다고 가정한다면요,

state = {
    number: 0,
    foo: {
      bar: 0,
      foobar: 1
    }
  }

아래와 같이 한다고 해서 foobar 값이 업데이트 되지 않습니다.

this.setState({
  foo: {
    foobar: 2
  }
})

이렇게 하게된다면 그냥 기존의 foo 객체가 바뀌어버립니다.

{
  number: 0,
  foo: {
    foobar: 2
  }
}

그 대신에 위와 같은 상황에서는 이렇게 해주어야합니다:

this.setState({
  number: 0,
  foo: {
    ...this.state.foo,
    foobar: 2
  }
});

... 은 자바스크립트의 전개연산자 입니다. 기존의 객체안에 있는 내용을 해당 위치에다가 풀어준다는 의미죠. 그 다음에, 우리가 설정하고 싶은 값을 또 넣어주면 해당 값을 덮어쓰게 됩니다.

👉setState에 객체 대신 함수를 전달하기
setState 를 사용하여 값을 업데이트하게 될 때, 기존의 값을 참고하여 값을 업데이트를 하게 될 때, 조금 더 나은 문법으로 할 수 있습니다
기존에 작성했던 코드는 이랬죠?

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

굳이 또 this.state 를 조회해야 하는데요, 이렇게 하면 조금 더 멋진 문법으로 작성 할 수 있습니다.

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

setState 에 updater 함수를 만들어서 전달해 주었습니다. 여기서 조금 더 나아가면 이렇게 작성 할 수 있습니다.

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

==

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

기존함수 또한 간단히 해볼수있습니다.

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

  handleDecrease = () => {
    this.setState(
      ({ number }) => ({
        number: number - 1
      })
    );
  }

👉이벤트 설정
render 함수에서 이벤트 설정을 한 부분을 확인해봅시다.

render() {
    return (
      <div>
        <h1>카운터</h1>
        <div>: {this.state.number}</div>
        <button onClick={this.handleIncrease}>+</button>
        <button onClick={this.handleDecrease}>-</button>
      </div>
    );
  }

버튼이 클릭되면 우리가 준비한 함수가 각각 호출되도록 설정해주었습니다.

<button onclick="alert('hello');">Click Me</button>

html 에서는 onclick 속성에 클릭되면 실행 할 자바스크립트를 문자열 형태로 넣어줍니다. 반면 우리가 작성한 코드를 다시 봐보세요.

<button onClick={this.handleIncrease}>+</button>

⚡여기서 정말로 주의해 주어야 하는데, 리액트에서 이벤트 함수를 설정할때 html 과 다음과 같은 사항이 다르다.

  • 이벤트이름을 설정 할 때 camelCase로 설정해주어야 한다.
  • 이벤트에 전달해주는 값은 함수 여야 한다. 만약에 onClick={this.handleIncrease()} 이런식으로 하게 된다면, 렌더링을 할 때 마다 해당 함수가 호출이된다. 그렇게 되면 렌더링 -> 함수 호출 -> setState -> 렌더링 -> 함수 호출 -> 무한반복.. 이렇게 되버린다!
profile
기록하는 습관을 기를 수 있을까....?!

0개의 댓글