State and Lifecyle

ho_vi·2023년 9월 19일

React

목록 보기
4/19
post-thumbnail

리액트에서 state 컴포넌트 내부에서 바뀔 수 있는 값을 의미합니다. props는 컴포넌트가 사용되는 과정에서 부모 컴포넌트가 설정하는 값이며, 컴포넌트 자신은 props를 읽기 전용으로만 사용할 수 있습니다. props를 바꾸려면 부모 컴포넌트에서 바꾸어 주어야 합니다. 예를 들어 현재 상황에서는 App 컴포넌트에서 MyComponent를 사용할 때 props를 바꾸어 주어야 값이 변경될 수 있습니다.

리액트에는 두 가지 종류의 state가 있습니다.

  • 클래스 컴포넌트가 가지고 있는 state
  • 함수 컴포넌트 useState라는 함수를 통해 사용하는 state

코드 구현 및 설명

  • 컴포넌트에 state를 설정 할 때는 constructor를 작성하여 설정 합니다.
  • render 함수에서 현재 state를 조회할 때는 this.state를 조회하면 됩니다.
  • 이벤트로 설정 할 함수를 넣어 줄 때는 화살표 함수 문법을 사용해야 합니다.
  • 함수 내부에서 this.setState라는 함수를 사용하는데, 이 함수가 state 값을 변경해 줍니다.
import { Component } from "react";

class Counter extends Component {
    constructor(props) {
        super(props);
				// state의 초기값 설정하기
        this.state = {
            number: 0
        };
    }
    render() {
        const {number} = this.state; // state 조회
        return (
            <div>
                <h1>{number}</h1>
                {/* this.setState를 사용하여 state에 새로운 값을 넣을 수 있습니다. */}
                <button onClick = {()=>{this.setState({number: number + 1})}}>+1</button>
            </div>
        );
    }
}
export default Counter;

state 객체 안에 여러 값이 있을 때

state 객체 안에는 여러 값이 있을 수 있습니다.

state 안에 fixedNumber라는 또 다른 값을 추가해 주었습니다. 버튼이 클릭될 때 fixedNumber 값은 그대로 두고 number 값만 변경 합니다.

import { Component } from "react";

class Counter extends Component {
    constructor(props) {
        super(props);
		// state의 초기값 설정하기
        this.state = {
            number: 0,
            fixedNumber: 0
        };
    }
    render() {
        const {number, fixedNumber} = this.state; // state 조회
        return (
            <div>
                <h1>{number}</h1>
                <h2>바뀌지 않는 값 : {fixedNumber}</h2>
                {/* this.setState를 사용하여 state에 새로운 값을 넣을 수 있습니다. */}
                <button onClick = {()=>{this.setState({number: number + 1})}}>+1</button>
            </div>
        );
    }
}
export default Counter;

state를 constructor에서 꺼내기

아래와 같이 코드를 변경하면 constructor 메서드를 선언하지 않고도 state 초기값을 설정 할 수 있습니다.

state = {
    number: 0,
    fixedNumber: 0
};

생성주기 메서드를 클래스에 추가하기

  1. <Clock />가 root.render()로 전달되었을 때 React는 Clock 컴포넌트의 constructor를 호출합니다. Clock이 현재 시각을 표시해야 하기 때문에 현재 시각이 포함된 객체로 this.state를 초기화합니다. 나중에 이 state를 업데이트할 것입니다.
  2. React는 Clock 컴포넌트의 render() 메서드를 호출합니다. 이를 통해 React는 화면에 표시되어야 할 내용을 알게 됩니다. 그 다음 React는 Clock의 렌더링 출력값을 일치시키기 위해 DOM을 업데이트합니다.
  3. Clock 출력값이 DOM에 삽입되면, React는 componentDidMount() 생명주기 메서드를 호출합니다. 그 안에서 Clock 컴포넌트는 매초 컴포넌트의 tick() 메서드를 호출하기 위한 타이머를 설정하도록 브라우저에 요청합니다.
  4. 매초 브라우저가 tick() 메서드를 호출합니다. 그 안에서 Clock 컴포넌트는 setState()에 현재 시각을 포함하는 객체를 호출하면서 UI 업데이트를 진행합니다. setState() 호출 덕분에 React는 state가 변경된 것을 인지하고 화면에 표시될 내용을 알아내기 위해 render() 메서드를 다시 호출합니다. 이 때 render() 메서드 안의 this.state.date가 달라지고 렌더링 출력값은 업데이트된 시각을 포함합니다. React는 이에 따라 DOM을 업데이트합니다.
  5. Clock 컴포넌트가 DOM으로부터 한 번이라도 삭제된 적이 있다면 React는 타이머를 멈추기 위해 componentWillUnmount() 생명주기 메서드를 호출합니다.
import { Component } from "react";

class Clock extends Component {
    constructor(props) {
      super(props);
      this.state = {date: new Date()};
    }
  
    componentDidMount() {
      this.timerID = setInterval(
        () => this.tick(),
        1000
      );
    }
  
    componentWillUnmount() {
      clearInterval(this.timerID);
    }
  
    tick() {
      this.setState({
        date: new Date()
      });
    }
  
    render() {
      return (
        <div>
          <h1>Hello, world!</h1>
          <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
        </div>
      );
    }
  }

export default Clock;

함수 컴포넌트에서 useState 사용하기

리액트 16.8 이전 버전에서는 함수 컴포넌트에서 state를 사용할 수 없었습니다. 하지만 16.8 부터는 useState라는 함수를 사용하여 함수 컴포넌트에서도 state를 사용할 수 있게 되었습니다. 사용법은 조금 다릅니다.

이 과정에서 Hooks라는 것을 사용 합니다.

배열 비구조화 할당

배열 안에 들어 있는 값을 쉽게 추출할 수 있도록 해 주는 문법 입니다.

const array = [1, 2];

const [one, two] = array;

useState 사용하기

  • useState 함수의 인자에는 상태의 초기값을 넣어 줍니다.
import React, {useState} from "react";

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

    return (
        <div>
            <button onClick={onClickEnter}>입장</button>
            <button onClick={onClickLeave}>퇴장</button>
            <h1 style={{color: val}}>{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;

state를 사용할 때 주의 사항

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

조건문이나 반복문에서 사용하는건 주의 해야 합니다.

시간 업데이트 하기

import {useState} from 'react';

const Clock = () => {
    const [date, setDate] = useState(new Date());

    const tick = () => {
        setDate(new Date());
    }    

    setInterval(tick, 1000);

    return (
        <div>
            <h1>현재 시간을 표시 합니다.</h1>
            <h2>현재 시간은 {date.toLocaleTimeString()}</h2>
        </div>
    )
}
export default Clock;

props와 state ?

props와 state는 둘 다 컴포넌트에서 사용하거나 렌더링할 데이터를 담고 있으므로 비슷해 보이지만 역할은 매우 다릅니다. props는 부모 컴포넌트가 설정하고, state는 컴포넌트 자체적으로 지닌 값으로 컴포넌트 내부에서 값을 업데이트 할 수 있습니다.

Lifecycle ?

라이프사이클은 총 세 가지, 즉 마운트, 업데이트, 언마운트 카테고리로 나눕니다.

업로드중..

마운트

DOM이 생성되고 웹 브라우저상에 나타나는 것을 마운트라고 합니다.

  • constructor : 컴포넌트를 새로 만들 때마다 호출되는 클래스 생성자 메서드 입니다.
  • getDerivedStateFromProps : props에 있는 값을 state에 넣을 때 사용하는 메서드 입니다.
  • render : 우리가 준비한 UI를 렌더링하는 메서드 입니다.
  • componentDidMount : 컴포넌트가 웹 브라우저상에 나나탄 후 호출되는 메서드 입니다.

업데이트

컴포넌트는 다음과 같은 총 네가지 경우에 업데이트 합니다.

  • props가 바뀔 때
  • state가 바뀔 때
  • 부모 컴포넌트가 리렌더링될 때
  • this.forceUpdate로 강제로 렌더링을 트리거할 때

언마운트

컴포넌트를 DOM에서 제거하는 것을 언마운트라고 합니다.

profile
FE 개발자🌱

0개의 댓글