[React] State

신세원·2020년 11월 7일
1

React

목록 보기
23/28
post-thumbnail

리액트 컴포넌트에서 다루는 데이터는 두가지로 나뉜다.

  1. state
  2. props

props는 나중에 배우겠지만, 미리 간단하게 설명하자면 props는 부모 컴포넌트가 자식 컴포넌트에게 주는 값이다. 단방향성 특징을 가지고 있어, 자식 컴포넌트가 부모 컴포넌트에서 값을 줄 수 없고, 자식 컴포넌트는 props를 받아오기만 할뿐, 받아온 props는 직접 수정할 수 없다.

#What State?

위에서 props는 직접 수정할 수 없다고 이야기했다. 그렇다면 state는 어떨까?
state는 컴포넌트 내에서 값이 변할수 있다.
그렇기에 리액트에서 유동적인 데이터를 사용 할 때 state를 사용한다. 단어 자체로 '상태'이고,
간단하게 정리하자면,

state컴포넌트 내에 별도의 상태가 필요할 때 사용된다.

#How use State?

위에서 말로만 설명해도 직접 사용해보지 않는 이상 감이 오질 않는다. 이제 state의 사용방법에 대해 알아보자.

state는 해당 컴포넌트의 초기값이라고 보면 된다. 그래서 초기값 설정이 필수이며, 생성자(constrctor)에서 this.state={} 로 설정한다.

(React.js 16.8부터 함수형 컴포넌트에서도 state를 사용할 수 있다.여기서는 class형 컴포넌트에 대해서만 설명하겠다.)


state의 값을 변경할때 state를 직접 조작해서는 안되며, 상태 변경이 필요할때는 setState메소드를 이용해야 한다.

리액트는 state가 변경될 때마다 변경된 부분을 감지하여 리렌더링을 하는데 setState메소드를 사용하지 않고 직접 state 값을 수정할 경우 변경을 감지하지 못해서 리렌더링을 하지 못한다.
ex) this.state=...; ❌


1. constructor

컴포넌트의 생성자를 구현할 때는 super(props)를 선언을 권고한다.
이유는 this.props 사용 시 생성자 내에서 정의되지 않아 버그 발생 가능성이 생기기 때문이다.

리액트에서 컴포넌트를 생성할 때, state 값을 초기화, 메소드 바인딩할 때 constructor()를 사용한다.
리액트의 컴포넌트의 생성자는 해당 컴포넌트가 마운트 되기 전 호출된다.
우리가 constructor에서 super(props)를 호출한 이유는, 우리가 컴포넌트를 만들게 되면서, React.Component를 상속했고, 우리가 이렇게 constructor 를 작성하게 되면 기존의 클래스 생성자를 덮어쓰게 된다.
그렇기에, 리액트 컴포넌트가 지니고있던 생성자를 super 를 통하여 미리 실행하고, 그 다음에 우리가 할 작업 (state 설정) 을 해주는 것이다.

*마운트:어떠한 것을 사용할 수 있는 상태로 준비하는 것
바인딩(Binding)- 프로그램의 어떤 기본 단위가 가질 수 있는 구성요소의 구체적인 값, 성격을 확정하는 것

constructor()를 사용할때 흔히 많이 하는 실수로 setState를 호출한다.
생성자 내에서는 setState를 사용하는 것이 아닌 this.state로 초기값을 할당해주어야 한다.

생성자는 this.state를 직접 할당할 수 있는 곳으로 그 외에는 꼭 this.setState()를 사용하자.

생성자 내에서는 구독 작업이나 외부 API 호출을 하면 안 된다. 외부 API 호출이 필요하다면 componentDidMount()를 사용 하도록 하자.

componentWillMount()를 사용하시던 분들이라면 componentDidMount()로 함수를 수정해주세요. 현재 리액트에서 componentWillMount를 삭제 예정이므로 이제 이 함수를 사용하면 안돼요.

2.setState

constructor 안에서 state값을 설정하는 것은 가능하고, 생성된 후 state값을 바꾸는 방법은 setState를 사용한다.

state를 변경하기 위해서는 setState() 메소드를 사용한다. 그리고 이 메소드는 비동기적으로 작동한다.
즉, setState() 함수를 사용해서 state를 업데이트 하더라도 즉시 반영되지 않는다는 뜻이다.

  1. setState(updater[callback])
  2. updater:(state,props)=> stateChange

첫번째 인수 updater함수로 전달된 state는 최신 값(기존의 값에서 변하게 만드려는 값)이다. 최신 값으로 상태를 업데이트 한다.
두번째 인수 callback은 setState의 실행이 완료되고 컴포넌트가 렌더링 된 뒤에 실행될 함수이다.(생략가능하다.)

현재 state에서 age 속성을 1씩 증가시키는걸 확인할 수 있다.
또한, setState 함수에 첫번째 인수에 객체를 전달하여 state를 업데이트 할 수 있다.

첫번째 인수에 함수를 할당해 state를 업데이트 하는 동작과 동일한 결과를 나타낸다.

3. 이벤트 설정

  1. state로 기본값 설정 완료
  2. setState로 최신 값(기존에서 변하게 만드려는 값) 설정완료
  3. 이벤트 설정으로 원하는 동작실행

이제 render함수에서 이벤트를 설정하는 방법에 대해 알아보자.


import React from "react";

class App extends React.Component{
  constructor(props){
    super(props);
    this.state = {
      name: 'sewon',
      age:20,
      hobby:'coding'
    };
  }
  
  
  changeAgeHandler=()=>{
  const {age} = this.state; //구조분해 할당
  this.setState({age:age+1})
  }
  
   render() {
    const{name,age,job} = this.state;
    return (
      <div>
        <div>name:{name}</div> //name:sewon
        <div onClick={this.changeAgeHandler}>age:{age}</div> //age:21
        <div>hobby:{hobby}</div> // hobby:coding
      </div>
      );
    }
  }

export default App;

이벤트를 작성할때 알아야할 정보들이 있다.

  • 리액트에서는 이벤트 속성에 대해 camelCase로 작성한다
    ex)onclick -> onClick
  • 이벤트 속성의 함수는 문자열이 아닌, {this.changeAgeHandler} 또는 {(e)=> this.changeAgeHandler(e)}로 작성하여야 한다.
    {this.changeAgeHandler}로 작성이 가능한 이유는 {this.changeAgeHandler}가 Arrow Function으로 작성되었기 때문에 bind(this)를 사용할 필요가 없기 때문이다.
profile
생각하는대로 살지 않으면, 사는대로 생각하게 된다.

0개의 댓글