[React] Event Handling

문지은·2023년 7월 15일
0

React

목록 보기
7/24
post-thumbnail

이벤트 처리하기

  • 이벤트
    • 사용자가 버튼을 클릭하는 등의 사건을 의미
  • DOM의 이벤트
    • 이벤트의 이름을 모두 소문자로 표기
    • 이벤트를 처리할 함수를 문자열로 전달
    • ex) 클릭 이벤트를 처리하는 onclick
<button onclick="activate()">
  Activate
</button>
  • 리액트의 이벤트
    • 이벤트의 이름을 카멜 표기법으로 표기
    • 이벤트를 처리할 함수를 그대로 전달
<button onClick={activate}>
  Activate
</button>

이벤트 핸들러(Event Handler)

  • 이벤트가 발생했을 때 해당 이벤트를 처리하는 함수
  • 이벤트 리스너(Event Listener) 라고 부르기도 함

사용 방법

클래스 컴포넌트

  • 클래스의 함수로 정의하고 생성자에서 바인딩해서 사용
  • 예시 코드
    • 버튼을 클릭하면 이벤트 핸들러 함수 handleClick() 함수 호출
class Toggle extends React.Component {
    constructor(props) {
        super(props);

        this.state = { isToggleOn: true };

        // callback에서 this를 사용하기 위해서는 바인딩을 필수적으로 해야 함
        this.handleClick = this.handleClick.bind(this);
    }

    handleClick() {
        this.setState(prevState => ({
            isToggleOn: !prevState.isToggleOn
        }));
    }

    render() {
        return (
            <button onClick={this.handleClick}>
                {this.state.isToggleOn ? '켜짐' : '꺼짐'}
            </button>
        )
    }
}
  • 클래스 필드 문법도 사용 가능
class MyButton extends React.Component {
    handleClick = () => {
        console.log('this is: ', this);
    }

    render() {
        return (
            <button onClick={this.handleClick}>
                클릭
            </button>
        );
    }
}
  • arrow function을 사용하는 방법도 있음
class MyButton extends React.Component {
    handleClick() {
        console.log('this is:', this)
    }

    render() {
        // this 바운드하기
        return (
            <button onClick={() => this.handleClick()}>
                클릭
            </button>
        );
    }

}

함수 컴포넌트

  • 함수 안에 함수로 정의하거나 arrow function을 사용해서 정의
  • 위에서 작성한 Toggle 컴포넌트를 함수 컴포넌트로 변환하면 아래와 같다.
function Toggle(props) {
    const [isToggleOn, setIsToggleOn] = useState(true);

    // 방법 1. 함수 안에 함수로 정의
    function handleClick() {
        setIsToggleOn((isToggleOn) => !isToggleOn);
    }

    // 방법 2. arrow function을 사용해서 정의
    const handleClick = () => {
        setIsToggleOn((isToggleOn) => !isToggleOn);
    }

    return (
        <button onClick={handleClick}>
                {this.state.isToggleOn ? '켜짐' : '꺼짐'}
            </button>
    );
}

Argument 전달하기

  • Argument
    • 함수에 전달할 데이터
    • 파라미터 또는 매개변수라고 부르기도 함
  • 클래스 컴포넌트
    • arrow function을 사용하거나 Function.protptype.bind를 사용해서 전달
// arrow function 사용
<button onClick={(event) => this.deleteItem(id, event)}>삭제하기</button>

// Function.prototype.bind
<button onClick={this.deleteItem.bind(this, id}}>삭제하기</button>
  • 함수 컴포넌트
    • 이벤트 핸들러 호출 시 원하는 순서대로 매개변수를 넣어서 사용
function MyButton(props) {
    const handleDelete = (id, event) => {
        console.log(id, event.target)
    }

    return (
        <button onClick={(event) => handleDelete(1, event)}>삭제하기</button>
    );
}

실습 - 클릭 이벤트 처리하기

ConfirmButton 컴포넌트 만들기

  • Confirm 여부를 저장하기 위해 state에 초깃값이 false인 isConfirmed 변수 만들기
  • 버튼의 onClick 이벤트를 처리하기 위해 이벤트 핸들러로 handleConfirm 함수 생성
// src/chapter_08/ConfirmButton01.jsx

import React from 'react'

class ConfirmButton01 extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
            isConfirmed: false,
        };

        this.handleConfirm = this.handleConfirm.bind(this);
    }

    handleConfirm() {
        this.setState((prevState) => ({
            isConfirmed: !prevState.isConfirmed
        }));
    }

    render() {
        return (
            <div>
                <h1>ConfirmButton 컴포넌트 만들기</h1>
                <button
                    onClick={this.handleConfirm}
                    disabled={this.state.isConfirmed}
                >
                    {this.state.isConfirmed ? "확인됨" : "확인하기"}
                </button>
            </div>
        )
    }

}

export default ConfirmButton01;
  • ConfirmButton 컴포넌트를 렌더링하기 위해 index.js 파일 수정
// src/index.js

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';

import ConfirmButton01 from './chapter_08/ConfirmButton01';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <ConfirmButton />
  </React.StrictMode>
);

reportWebVitals();
  • 버튼 생성 확인

  • 클릭하면 비활성화됨

클래스 필드 문법 사용하기

  • 위에서 만든 ConfirmButton 컴포넌트의 이벤트 핸들러를 클래스 필드 문법을 사용해서 변경해보자.
  • 위에서 작성한 코드에서 bind() 코드를 제거한 후 이벤트 핸들러를 arrow function을 사용하도록 수정
// src/chapter_08/ConfirmButton02.jsx

import React from 'react'

class ConfirmButton02 extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
            isConfirmed: false,
        };

    }

    handleConfirm = () => {
        this.setState((prevState) => ({
            isConfirmed: !prevState.isConfirmed
        }));
    }

    render() {
        return (

            <div>
                <h1>클래스 필드 문법 사용</h1>
                <button
                    onClick={this.handleConfirm}
                    disabled={this.state.isConfirmed}
                >
                    {this.state.isConfirmed ? "확인됨" : "확인하기"}
                </button>
            </div>
        )
    }

}

export default ConfirmButton02;
  • index.js 수정
// src/index.js

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';

import ConfirmButton01 from './chapter_08/ConfirmButton01';
import ConfirmButton02 from './chapter_08/ConfirmButton02';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <ConfirmButton01 />
    <ConfirmButton02 />
  </React.StrictMode>
);

reportWebVitals();
  • 동일한 결과가 나옴을 확인할 수 있음

함수 컴포넌트로 변경하기

  • 위에서 작성한 컴포넌트를 함수 컴포넌트로 변경하기
  • state는 useState() 훅을 사용하여 처리하고 이벤트 핸들러는 arrow function을 사용해서 만듦
// src/chapter_08/ConfirmButton03.jsx

import React, { useState } from "react";

function ConfirmButton03(props) {
    const [isConfirmed, setIsConfirmed] = useState(false);

    const handleConfirm = () => {
        setIsConfirmed((prevIsConfirmed) => !prevIsConfirmed);
    };

    return (
        <div>
            <h1>함수 컴포넌트 사용</h1>
            <button onClick={handleConfirm} disabled={isConfirmed}>
                {isConfirmed ? "확인됨" : "확인하기"}
            </button>
        </div>
    );
}

export default ConfirmButton03;
  • index.js 수정
// src/index.js

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';

import ConfirmButton01 from './chapter_08/ConfirmButton01';
import ConfirmButton02 from './chapter_08/ConfirmButton02';
import ConfirmButton03 from './chapter_08/ConfirmButton03';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <ConfirmButton01 />
    <ConfirmButton02 />
    <ConfirmButton03 />
  </React.StrictMode>
);

reportWebVitals();
  • 결과 확인

실습 전체 코드

References

profile
코드로 꿈을 펼치는 개발자의 이야기, 노력과 열정이 가득한 곳 🌈

0개의 댓글