[코낭] 4.2 예제로 이벤트 핸들링 익히기 / 4.3 함수 컴포넌트로 구현해 보기

최정윤·2023년 5월 8일
0

코낭

목록 보기
15/41

4.2.3 임의 메서드 만들기

  • 이벤트에 실행할 자바스크립트 코드를 전달하는 것이 아니라, 함수 형태의 값을 전달한다.
  • 때문에 이벤트를 처리할 때 렌더링을 하는 동시에 함수를 만들어서 전달해준다. 아니면 함수를 미리 준비하여 전달하는 방법도 있다.
  • 성능상으로 차이가 거의 없지만, 가독성이 좋다.

4.2.3.1 기본 방식

▶ EventPractice.js

import { 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;

  • 함수가 호출될 때 this는 호출부에 따라 결정되고, 클래스의 임의 메서드가 특정 HTML요소의 이벤트로 등록되는 과정에서 메서드와 this의 관계가 끊어진다.
  • 임의 메서드가 이벤트로 등록되어도 this가 컴포넌트 자신으로 제대로 가리키기 위해 메서드를 this와 바인딩하는 작업이 필요하다.
  • 바인딩하지 않는 경우라면 this가 undefined를 가리키게 된다.

4.2.3.2 Property Initializer Syntax를 사용한 메서드 작성

  • 메서드 바인딩은 생성자 메서드에서 하는 것이 정석이지만 constructor을 수정해야 하기 때문에 불편하게 느낄 수 있다.
  • 바벨의 transform-class-properties 문법을 사용하여 화살표 함수 형태로 메스드를 정의하여 좀 더 간단히 작업할 수 있다.
    ▶ EventPractice.js
import { 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;
  • 출력 화면은 이전 화면과 같다.

4.2.4 input 여러 개 다루기

  • input이 여러 개일 때는 event 객체를 활용하여 e.target.name 값을 사용하면 된다.
  • onChange 이벤트 핸들러에서 e.target.name은 해당 인풋의 name을 가리킨다.
import { Component } from 'react';

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

    handleChange = (e) => {
        this.setState({
            [e.target.name]: e.target.value
        });
    }

    handleClick = () => {
        alert(this.state.username + ': ' + this.state.message);
        this.setState({
            username: '',
            message: ''
        });
    }

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

export default EventPractice;

  • handleChange 함수에서 key를 [ ]로 감싸면 그 안에 넣은 레퍼런스가 가리키는 실제 값이 key 값으로 사용된다.
    [예시코드]
const name = 'variantKey';
const object = {
	[name]: 'value'
};

[결과]

{
  'variantKey': 'value'
}

4.2.5 onKeyPress 이벤트 핸들링

import { Component } from 'react';

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

    handleChange = (e) => {
        this.setState({
            [e.target.name]: e.target.value
        });
    }

    handleClick = () => {
        alert(this.state.username + ': ' + this.state.message);
        this.setState({
            username: '',
            message: ''
        });
    }

    handleKeyPress = (e) => {
        if(e.key === 'Enter') {
            this.handleClick();
        }
    }

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

export default EventPractice;
  • handleKeyPress 메서드를 호출하여 텍스트를 입력하고 enter버튼을 눌러 handleClick 메서드가 실행될 수 있다.

4.3 함수 컴포넌트로 구현해 보기

이전에 작업한 코드를 함수 컴포넌트로 구현해보자.

import { useState } from 'react';

const EventPractice = () => {
    const [username, setUsername] = useState('');
    const [message, setMessage] = useState('');
    const onChangeUsername = e => setUsername(e.target.value);
    const onChangeMessage = e => setMessage(e.target.value);
    const onClick = () => {
        alert(username + ': ' + message);
        setUsername('');
        setMessage('');
    };
    const onKeyPress = e=> {
        if(e.key === 'Enter') {
            onClick();
        }
    };
    return (
        <div>
            <h1>이벤트 연습</h1>
            <input
                type="text"
                name="username"
                placeholder="사용자명"
                value={username}
                onChange={onChangeUsername}
            />
            <input
                type="text"
                name="message"
                placeholder="아무거나 입력해 보세요"
                value={message}
                onChange={onChangeMessage}
                onKeyPress={onKeyPress}
            />
            <button onClick={onClick}>확인</button>
        </div>
    );
}

export default EventPractice;
  • e.target.name을 활용하지 않고 onChange 관련 함수 두 개를 따로 만들어 주었다.
  • 인풋 개수가 많아질 것 같으면 e.target.name을 활용하는 것이 더 좋을 수도 있다.
profile
개발 기록장

0개의 댓글