공부 기록

[react] 이벤트 핸들링

by 너나나

사용자가 웹 브라우저에서 DOM 요소들과 상호 작용하는 것을 이벤트라고 한다!! 리액트에서 이벤트 다루는 법을 알아보자!!

 

EventPractice.js 라는 새 컴포넌트를 만들었다!!

import React, { Component } from 'react';

class EventPractice extends Component {
    render() {
        return (
            <div>
                <h1>이벤트 연습</h1>
                <input
                    type="text"
                    name="message"
                    placeholder="아무거나 입력해 보세요"
                    onChange={
                        (e) => {
                            console.log(e)
                        }
                    }
                />
            </div>
        )
    }
}

export default EventPractice;

App.js에 EventPractice를 렌더링 해주는거 잊지말고!!!

import React from "react";
import './App.css';
import EventPractice from "./EventPractice";

const App = () => {
 return <EventPractice />
}
export default App;

실행시키고 개발자도구를 열어서 인풋에 아무거나 입력해보면!!!!

 

이렇게 텍스트 필드에 텍스트가 입력될때 마다 변화가 발생했다고!! 콘솔에서 소리질러준다!!

 onChange={
	(e) => {
		console.log(e)
        }
}

우리가 input 태그 안에 onChange 그러니까 변화가 일어나면 그 변화를 콘솔에 띄워달라!!! 이렇게 적어서 이런 이벤트가 발생한것이다!! 이렇게 이벤트가 발생했으면 좋겠는 친구에 뭐 클릭했을때 이거 해라, 변화가 있을때 이거해라 를 onClick, onChange 같은 리액트에서 지원하는 이벤트를 이용해서 구현할 수 있다!!

 

그러면 state에 input 값을 담아보자!!!

EventPractice.js를 수정!!

import React, { Component } from 'react';

class EventPractice extends Component {
    state = {
        message: ''
    }
    render() {
        return (
            <div>
                <h1>이벤트 연습</h1>
                <input
                    type="text"
                    name="message"
                    placeholder="아무거나 입력해 보세요"
                    value = {this.state.message}
                    onChange = {
                        (e) => {
                            this.setState({
                                message: e.target.value
                            })
                        }
                    }
                />
                <button onClick = {
                    () => {
                        alert(this.state.message);
                        this.setState({
                            message: ''
                        });
                    }
                }>확인</button>
            </div>
        )
    }
}

export default EventPractice;

input에 변화가 발생하면 state인 message를 그 변화한 값으로 바꿔주고

onChange = {
	(e) => {
		this.setState({
			message: e.target.value
        })
    }
}

버튼을 눌렀을때 이 message를 alert으로 띄워주고 그 다음 메세지는 다시 없애준다!!

 

이렇게 내가 쓴 메세지가 확인 버튼을 누르면 잘 띄워지고 이 다음 작성한 메세지는 사라진다!!

 

이렇게 이벤트를 처리할 때 안에 함수를 만들어서 전달해줄 수 있는데 이 함수들을 밖으로 빼서 미리 준비하여 전달하는 방법도 있다!! 이 방법이 가독성이 훨씬 높다고 한다!!

앞서 만든 친구들의 onChange와 onClick에 전달한 함수를 따로 빼내서 컴포넌트 임의 메서드를 만들어보자!!!

import React, { Component } from 'react';

class EventPractice extends Component {
    state = {
        message: ''
    }

    constructor(props) {
        super(props);
        this.handleChange = this.handleChange.bind(this);
        this.handleClick = this.handleClick.bind(this);
    }

    handleChange(e) {
        this.setState({
            message: e.target.value
        });
    }
    
    handleClick() {
        alert(this.state.message);
        this.setState({
            message: ''
        });
    }

    render() {
        return (
            <div>
                <h1>이벤트 연습</h1>
                <input
                    type="text"
                    name="message"
                    placeholder="아무거나 입력해 보세요"
                    value = {this.state.message}
                    onChange = {this.handleChange}
                />
                <button onClick = {this.handleClick}>확인</button>
            </div>
        )
    }
}

export default EventPractice;

그냥 저번에 onChange, onClick 안에 만들었던 친구들을 handleChange와 handleClick라는 이름으로 밖으로 빼준것 뿐이다!!

근데 함수가 호출될 때 this는 호출부에 따라 결정되므로 클래스의 임의 메서드가 특정 html 요소의 이벤트로 등록되는 과정에서 메서드와 this의 관계가 끊어져버린다. 그래서 임의 메서드가 이벤트로 등록되어도 this를 컴포넌트 자신으로 제대로 가리키기 위해서 메서드와 this를 바인딩 하는 작업이 필요하다!! 여기서 constructor 함수에서 바인딩 하는 작업이 이루어지고있다.

 

그러니까 그냥 저렇게 내가 밖으로 빼서 만든 메서드를 이벤트로 등록해주려면 바인딩해주는 과정이 필요하다는거다!! 그 바인딩을

constructor(props) {
	super(props);
    this.handleChange = this.handleChange.bind(this);
    this.handleClick = this.handleClick.bind(this);
}

이렇게 해준거고!! 이렇게 메서드 바인딩을 생성자 메서드(constructor)에서 하는것이 정석이라고 한다. 그런데 이러면 새 메서드를 만들 때마다 constructor도 수정해줘야 한다. 바벨의 transform-class-properties 문법을 사용해서 화살표 함수 형태로 메서드를 정의하면 훨씬 간단하게 작성할 수 있다!!

import React, { Component } from 'react';

class EventPractice extends Component {
    state = {
        message: ''
    }

    handleChange = (e) => {
        this.setState({
            message: e.target.value
        });
    }
    
    handleClick = () => {
        alert(this.state.message);
        this.setState({
            message: ''
        });
    }

    render() {
        return (
            <div>
                <h1>이벤트 연습</h1>
                <input
                    type="text"
                    name="message"
                    placeholder="아무거나 입력해 보세요"
                    value = {this.state.message}
                    onChange = {this.handleChange}
                />
                <button onClick = {this.handleClick}>확인</button>
            </div>
        )
    }
}

export default EventPractice;

 


참고 자료

「리액트를 다루는 기술 - 김민준」

 

'study > react (2021 여름방학)' 카테고리의 다른 글

[react] 라이프사이클 메서드  (0) 2021.07.24
[react] 컴포넌트 반복  (0) 2021.07.18
[react] DOM에 이름 달기 ref  (0) 2021.07.17
[react] props, state  (0) 2021.07.13
[react] 리액트 정리 - 1  (0) 2021.07.11

블로그의 정보

공부 기록

너나나

활동하기