개발 공부한 것들/SeSSAC 웹 풀스텍 과정 회고록

[SeSSAC] 웹 풀스택 영등포 5기 과정_REACT(2)_state

geograp 2023. 10. 2. 22:09

react를 배운 지 이틀 되었다....

여전히 혼돈의 카오스지만, 좋은 프론트를 위해 복습을 시작해 보자 ^_______^

 


 

0. state란?

React에서 앱의 유동적인 데이터를 다루기 위한 객체

사용하는 이유는 State가 변경될 시 자동으로 재렌더링 되기 때문이다.

 


 state의 클래스형 활용부터 코드를 통해 보자.

 

import React, { Component } from 'react';

class Counter extends Component {
    constructor(props) {
      super(props);
    this.state = {
      number: 0,
    }
  }
  render() {
    const { number } = this.state;
    return(
        <div>
            <h1>{number}</h1>
            {/* <h1>{this.state.number}</h1> */}
            <button
                onClick={() => {this.setState({number: number+1})}}>
                    +1</button>
            <button onClick={()=>  alert(number)}>Alert Number</button>
        </div>
    )
  }
}

export default Counter;

 

이 코드는 Counter라는 클래스를 만들어서 JSX를 통해 우리 눈으로 보여주고 있습니다.

 

class Counter extends Component {
  constructor(props) {
    super(props);

    this.state = {
      number: 0,
    };
  }

이 Counter라는 컴포넌트를 생성하면서 constructor라는 메서드를 사용하여 

'초기 상태'를 지정해주고 있습니다. 

this.state를 사용하여 number라는 변수를 0으로 초기화해주고 있습니다.

 

render() {
 const { number } = this.state;
   return(
      <div>
         <h1>{number}</h1>
         <button
            onClick={() => {this.setState({number: number+1})}}>
                +1</button>
         <button onClick={()=>  alert(number)}>Alert Number</button>
        </div>
   )
}

저번 시간에 배웠던 render와 return을 통해 JSX를 사용하고 있습니다.

처음 this.state에서 초기화해 줬던 number를 구조분해 할당으로 꺼내와 줍니다.

 

<div>로 감싸고 있는 내부 태그들을 살펴보면, number를 표시해 주고,

<button> 태그에 onClick으로 클릭 시 number의 상태가 변화하도록 [ setState ]를 통해 지정해주고 있습니다.

 

그리고 다른 button태그에는 넘버 자체를 alert 하는 버튼도 삽입하였습니다.

이 this.state와 setState를 통해 컴포넌트 내부에서만 상태 변화를 일으킬 수 있습니다.

 

 


이번에는 클래스형 컴포넌트가 아닌 함수형 컴포넌트에 state를 사용해 보도록 하겠습니다.

 

import { useState } from 'react';

const SayFunction = () => {
    console.log(useState);
    const [ message, setMessage ] = useState('welcome!');
    const onClickEnter = () => {
        setMessage('안녕하세요!')
    }
    const onClickLeave = () => {
        setMessage('안녕히가세요~')
    }
    return (
        <div>
            <button onClick={onClickEnter}>입장</button>
            <button onClick={onClickLeave}>퇴장</button>
            <h1>{message}</h1>
        </div>
    )
}

export default SayFunction;

 

이 코드도 한 줄씩 보면서 어떻게 사용할 수 있는지 보도록 하겠습니다.

 

import { useState } from 'react';

react 패키지에서  [ useState ] 함수를 불러와서 사용해 줍니다.

클래스형과 달리 함수형 컴포넌트에서 원래 이 state 사용이 불가했는데, React16.8 버전 이후부터

이 useState 함수를 통해 함수형에서도 가능해졌다는 점!!!

 

const [message, setMessage] = useState('welcome!');

이 useState함수를 통해 message라는 상태 관련 변수를 선언하고, 초기값을 'welcome!'이라고 넣고 있습니다.

그리고 옆에 있는 setMessage함수입니다.

message변수값을 변화시킬 수 있는 함수로, 1. 기존 상태를 이용한 업데이트나,

2. 새로운 상태값을 전달하는 업데이트를 실행할 수 있습니다.

 

const onClickEnter = () => {
        setMessage('안녕하세요!')
}
const onClickLeave = () => {
    setMessage('안녕히가세요~')
}

 

이는 onClickEnter함수와 onClickLeave함수를 정의하고 있습니다.

여기서 아까 선언만 했던 setMessage 함수로 새로운 상태값을 저장했습니다.

 

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

이 리턴값에서 JSX를 통해 button과 message를 보여주고 있습니다.

처음에는 이 message가 'welcome!'이었다가 입장을 누르면 '안녕하세요!', 퇴장을 누르면 '안녕히가세요~'라고 바뀝니다.

 

 


1. React의 Event

React에서 Event를 사용하다면, Html과는 약간,,, 다른 형태를 가지고 있습니다.

 

여기 몇 가지 규칙이 있어서 알아보도록 하겠습니다.

 

(1) React는 소문자가 아닌 카멜케이스(camelCase)를 사용한 이벤트명 사용

<button onClick={}></button>

onclick (X) onClick(O)

 

(2) JSX를 사용하여 이벤트 핸들러를 전달 (함수 자체를 전달한다는 의미)

<button onClick={activeEvent}></button>

onClick={activeEvent( )} (X) onClick={activeEvent} (O)

 

(3) 기본 DOM요소에만 이벤트를 설정할 수 있다.

 


 

또한 React는 합성 이벤트(Synthetic Event)를 사용합니다.

합성 이벤트는 React가 제공하는 이벤트 시스템의 일부로, 웹브라우저의 nativeEvent가 아닌

nativeEvent를 감싸고 있는 SyntheticEvent로 React의 이벤트 핸들러를 통해 사용됩니다.

 

수업시간 예제를 통해 합성 이벤트의 기초에 대해 알아봅시다.

export default function SyntheticEvent() {
    function syntheticEvent(e) {
        console.log('Synthetic Event 버튼 클릭!');
    }
    function printInputValue(e) {
        console.log(e.target.value);
    }
    return (
        <div>
            <button onClick={syntheticEvent}>SyntheticEvent 콘솔에 찍기</button>
            <br></br>
            <input type="text" placeholder="입력하세요" onChange={printInputValue}></input>
        </div>
    )
}

 

이 함수는 "SyntheticEvent 콘솔에 찍기" 버튼을 누르면 

console에 'Synthetic Event 버튼 클릭!'이 콘솔에 찍히게 하고

input text 칸에 입력된 value들이 console에 찍히게 하는 SyntheticEvent함수입니다.

 

  function printInputValue(e) {
    console.log(e.target.value);
  }

 

이 printInputValue함수가 합성이벤트를 활용한 함수입니다.

 

여기 input변수에 입력된 e는 합성 이벤트 객체를 가리킵니다.

(물론 변수명은 변경가능하며, 이 함수에 변수명을 받는 것 자체가 합성이벤트 객체를 받아들인다는 뜻입니다.)

e 객체를 console.log에 찍어보면 굉장히 다양한 내용을 품고 있는 합성 이벤트 객체를 볼 수 있습니다.

 

여기서 e.target은 저희가 추후에 input 태그에 활용하므로, e.target은 이 이벤트가 쓰이는 input태그 요소를 말합니다.

 <input type="text" placeholder="입력하세요" onChange={printInputValue}></input>

 

그러므로 e.target.value는 결국 이 input태그에 입력된 사용자 value값을 말합니다.

    return (
        <div>
            <button onClick={syntheticEvent}>SyntheticEvent 콘솔에 찍기</button>
            <br></br>
            <input type="text" placeholder="입력하세요" onChange={printInputValue}></input>
        </div>
    )

이 JSX를 통해 html로 button과 input text요소를 보여주고 있습니다.

여기서 onClick 메서드를 활용하여 앞서 선언했던 systheticEvent를 통해 버튼을 누르면

'Systhetic Event 버튼 클릭!'이 콘솔에 찍히게 됩니다.

 

또한 input text 에는 onChange 메서드를 활용하여

input태그에 어떤 값을 넣어서 변화를 주게 되면 그 변화준 모든 과정이 printInputValue를 통해

콘솔에 찍히게 됩니다.


 

3. bind

 

클래스형 컴포넌트의 이벤트는this를 사용해야 함수를 찾아갈 수 있습니다.

그중에 이 bind는 this값을 영구적으로 설정하거나, 함수에 하나 이상의 인자를 영구적으로 

설정하기 위한 메서드입니다!

 

import { Component } from 'react'

class ClassBind extends Component {
    constructor(props) {
        super(props);
        console.log("constructor this >>> ", this);
        this.state = {
            name: 'sessac',
        }
        this.printConsole = this.printConsole.bind(this);
    }

    printConsole() {
        console.log('this >> ', this);
        console.log('state >> ', this.state);
    }

    printConsole2 = (msg) => {
        console.log("msg >>>", msg);
    }
    
    render() {
        return (
            <div>
                <h1>Class Component Event</h1>
                <button onClick={this.printConsole}>printConsole(인자x)</button>
                <button onClick={() => this.printConsole2('msg')}>printConsole(인자o)</button>
                <button onClick={this.printConsole2.bind(null, 'msg')}>printConsole(인자o, ,bind)</button>
            </div>
        )
    }
}

export default ClassBind;

수업 시간 예제를 통해 bind에 대해서 이해해 봅시다!

이 것도 한줄한줄 뜯어서 보도록 하겠습니다

 

    constructor(props) {
        super(props);
        console.log("constructor this >>> ", this);
        this.state = {
            name: 'sessac',
        }
        this.printConsole = this.printConsole.bind(this);
    }

ClassBind 컴포넌트에서 constructor를 통해 생성하는 부분입니다.

마지막 문장에서 printConsole메서드의 this가 항상 이 컴포넌트 자체를 가리키도록 bind로 묶어둡니다.

 

    printConsole() {
        console.log('this >> ', this);
        console.log('state >> ', this.state);
    }

이 printConsole 메서드는 console에 this와 this.state를 출력하는 함수입니다.

이 메서드는 앞서 bind를 통해 this가 항상 이 컴포넌트를 가리키도록 했기 때문에

컴포넌트의 this와 this.state로 접근할 수 있습니다.

 

    printConsole2 = (msg) => {
        console.log("msg >>>", msg);
    }

 

이 printConsole2는 인자를 받을 경우 이 인자를 onsole에 나타내는 함수입니다.

 

    render() {
        return (
            <div>
            <h1>Class Component Event</h1>
            <button onClick={this.printConsole}>printConsole(인자x)</button>
            <button onClick={() => this.printConsole2('msg')}>printConsole(인자o)</button>
            <button onClick={this.printConsole2.bind(null, 'msg')}>printConsole(인자o, ,bind)</button>
            </div>
        )
    }

이 JSX를 보게 되면 각각의 버튼을 눌렀을 때 앞서 선언했던 함수들이 실행되도록 했습니다.

 

첫 번째 버튼에서는 onClick 이벤트에 this.printConsole 함수를 직접 바인딩하여 사용하고, 인자를 전달하지 않습니다.

두 번째 버튼에서는 화살표 함수를 사용하여 this.printConsole2('msg')를 호출하고 'msg'를 인자로 전달합니다.

세 번째 버튼에서는 bind() 메서드를 사용하여 this.printConsole2.bind(null, 'msg')를 호출하고 'msg'를 인자로 전달합니다.

 

 

이로써 클래스 컴포넌트를 사용할 때 this의 변화로 인해 bind로 묶어두는 방법과, 화살표 함수로 this를 묶어두는 방법까지

알아보았습니다 :)

 

수고하셨습니다!