본문 바로가기
IT/React

state

by 봉즙 2019. 10. 27.

state : 컴포넌트 내부에서 바뀔수 있는 값을 의미. props는 컴포넌트가 사용되는 과정에서 부모 컴포넌트가 설정하는 값이며, 컴포넌트 자신은 해당 props를 읽기 전용으로만 사용 할 수 있다. props를 바꾸려면 부모 컴포넌트에서 바꿔주어야 한다.
state에는 클래스형 컴포넌트가 지니고 있는 state와 함수형 컴포넌트에서 useState 함수를 통해 사용하는 state 두가지가 있다.

컴포넌트에 state를 설정하기 위해서는 constructor 메서드를 설정 해야 한다. 또한 constructor(생성자) 작성시 super(props)를 반드시 호출 해주어야 한다. 이 함수가 호출되면 현재 클래스형 컴포넌트가 상속하고 있는 리액트의 Component 클래스가 지닌 생성자 함수를 호출해 준다. this.state를 통해 초기값 설정.

컴포넌트의 state는 객체 형식이어야 한다.

import React, { Component } from "react";

class Counter extends Component {
  constructor(props) {
    super(props);
    //state의 초기값 설정하기
    this.state = {
      number: 0
    };
  }
  render() {
    const { number } = this.state; //state를 조회 할 때는 this.state로 조회
    return (
      <div>
        <h1>{number}</h1>
        <button
          //onClick을 통해 버튼이 클릭되었을 때 호출할 함수 지정 onClikc이라는 값을 props로 넣어주었다.
          onClick={() => {
            //이벤트로 설정할 함수를 사용시에는 화살표 함수를 사용하여 넣어 주어야 한다.
            //this.setState를 사용하여 state에 새로운 값을 넣을 수 있다.
            this.setState({ number: number + 1 });
          }}
        >
          +1
        </button>
      </div>
    );
  }
}

export default Counter;

 

 

coustructor 메서드 사용 외에 state 초깃값 지정

import React, { Component } from "react";

class Counter extends Component {
  state = {
    number: 0,
    fixedNumber: 0
  };
  render() {
    const { number, fixedNumber } = this.state; //state를 조회 할 때는 this.state로 조회
    return (
      <div>
        <h1>{number}</h1>
        <h2>바뀌지 않는 값: {fixedNumber}</h2>
        <button
          //onClick을 통해 버튼이 클릭되었을 때 호출할 함수 지정 onClikc이라는 값을 props로 넣어주었다.
          onClick={() => {
            //이벤트로 설정할 함수를 사용시에는 화살표 함수를 사용하여 넣어 주어야 한다.
            //this.setState를 사용하여 state에 새로운 값을 넣을 수 있다.
            this.setState({ number: number + 1 });
          }}
        >
          +1
        </button>
      </div>
    );
  }
}

export default Counter;

 

this.setState에 객체 대신 함수 인자 전달

 아래와 같이 설정한다 해서 2번의 숫자가 올라가지 않는다. this.state값이 바로 바뀌는것이 아니기에 1씩 더해진다.

onClick = {() => 
	// this.setState 를 사용하여 state에 새로운 값을 넣을 수 있다.
    this.setState({ number: number+1});
    this.setState({ number: this.state.number+1});
}}

 

이를 해결하기 위해 this.setState사용시 객체 대신에 함수를 인자로 넣어준다.

import React, { Component } from "react";

class Counter extends Component {
  state = {
    number: 0,
    fixedNumber: 0
  };
  render() {
    const { number, fixedNumber } = this.state; //state를 조회 할 때는 this.state로 조회
    return (
      <div>
        <h1>{number}</h1>
        <h2>바뀌지 않는 값: {fixedNumber}</h2>
        <button
          //onClick을 통해 버튼이 클릭되었을 때 호출할 함수 지정 onClikc이라는 값을 props로 넣어주었다.
          onClick={() => {
            //이벤트로 설정할 함수를 사용시에는 화살표 함수를 사용하여 넣어 주어야 한다.
            //this.setState를 사용하여 state에 새로운 값을 넣을 수 있다.
            this.setState(prveState => {
              return {
                number: prveState.number + 1
              };
            });
            //위의 코드와 아래 코드는 완전히 똑같은 기능을하며, 아래코드는 함수에서 바로 객체를 반환한다.(화살표 함수에서 값을 바로 반환하고 싶다면 { }생략)
            this.setState(prveState => ({
              number: prveState.number + 1
            }));
          }}
        >
          +1
        </button>
      </div>
    );
  }
}

export default Counter;

 

동작 이후 특정 작업 실행

        <button
          onClick={() => {
            this.setState(
              {
                number: number + 1
              },
              () => {
                console.log("방금 setState가 호출되었습니다.");
                console.log(this.state);
              }
            );
          }}
        >

 

함수형 컴포넌트에서 useState

useState 함수의 인자에는 상태의 초깃값을 넣어 준다. 클래스형 컴포넌트에서 state 초깃값은 객체 형태를 넣어 주어야 하지만, useState는 반드시 객체가 아니여도 된다. 함수 호출시 배열이 반환되며, 배열의 첫번째 원소는 현재 상태이며, 두번째 원소는 상태를 바꿔주는 함수이다. 이 함수를 setter함수라 한다. 또한 배열의 비구조화 할당을 통해 이름을 자유롭게 지정할 수 있다.

import React, { useState } from "react";

const Say = () => {
  const [message, setMessage] = useState("");
  const onClickEnter = () => setMessage("안녕하세요!");
  const onClickLeave = () => setMessage("안녕히 가세요!");

  return (
    <div>
      <button onClick={onClickEnter}>입장</button>
      <button onClick={onClickLeave}>퇴장</button>
      <h1>ㅌ{message}</h1>
    </div>
  );
};

export default Say;

한 컴포넌트에서 useState를 여러번 사용할 수 있다.

import React, { useState } from "react";

const Say = () => {
  const [message, setMessage] = useState("");
  const onClickEnter = () => setMessage("안녕하세요!");
  const onClickLeave = () => setMessage("안녕히 가세요!");

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

  return (
    <div>
      <button onClick={onClickEnter}>입장</button>
      <button onClick={onClickLeave}>퇴장</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 Say;

 

※배열 비구조 할당 : 배열 안에 들어있는 값을 쉽게 추출 할 수 있도록 해준다.

const array = [1,2];
const one = array[0];
const two = array[1];
//array안에 있는 값을 one과 two에 담아준다.
//위의 코드를 배열 비구조화 할당 사용시
const array = [1,2];
const [one,two] = array;

 

state 사용시 주의사항 : state 값을 바꾸어야 할 때는 setState 혹은 useState를 통해 전달 받은 setter 함수를 사용해야 한다.
배열이나 객체 업데이트 시에는 사본을 반들고 그 사본에 값을 업데이트 한 후, 그 사본의 상태를 setState혼은 setter 함수를 통해 업데이트 한다.
객체에 대한 사본을 만들때에는spread 연산자라 불리는 ..을 사용하여 처리하고, 배열에 대한 사본을 만들때는 배열의 내장 함수들을 이용한다.

const object= { a:1, b:2, c:3};
const nexttObject = { ...object, b:2}; //사본을 만들어 b의 값만 덮ㅇㅇ처쓰지

const array = [
	{id: 1, value: true},
    {id: 2, value: true},
    {id: 3, value: false}
];

let nextArray = array.concat({ id:4});//새항목 추가
nextArray.filter(item => item.id !== 2); //id가 2인 항목 제거
nextArray.map(item => (item.id === 1 ?{...item, value:false} : item}}; //id가 1인 항목의 value false설정
    

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

ref  (0) 2019.10.29
이벤트 처리  (0) 2019.10.28
props  (0) 2019.10.27
모듈 내보내기, 불러오기  (0) 2019.10.27
클래스형 컴포넌트  (0) 2019.10.27

댓글