[React] Event 걸기

Mia:)·2021년 1월 25일
1
import React, { Component } from "react";

class EventPractice extends Component {
    render() {
        return (
            <div>
                <h1>이벤트 연습</h1>
                <input type="text" name="message" placeholder=" writing space" onChange={
                    (e) => {
                        console.log(e);
                    }
                } />
            </div>
        );
    }
}

export default EventPractice;


콘솔에 나오는 e객체는 SyntheticEvent로 웹 브라우저의 네이티브 이벤트를 감싸는 객체이다. SyntheticEvent는 네이티브 이벤트와 달리 이벤트가 끝나고 나면 이벤트가 초기화되므로 정보를 참조할 수 없다. 예를들어, 0.5 뒤에 e 객체를 참조하면 e객체 내부의 모든 값이 비워지게 된다. 만약 비동기적으로 이벤트 객체를 참조할 일이 있다면 e.persist()함수를 호출해 주어야 한다.

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=" writing space" value={this.state.message} onChange={this.handleChange} />
                <button onClick={this.handleClick}>confirm</button>
            </div>
        );
    }
}

export default EventPractice;

함수가 호출될 때 this는 호출부에 따라 결정되므로, 클래스의 임의 메서드가 특정 HTML요소의 이벤트로 등록되는 과정에서 메서드와 this의 관계가 끊어져버린다. 이 때문에 임의 메서드가 이벤트로 등록되어도 this를 컴포넌트 자신으로 제대로 가르키기 위해서는 메서드를 this와 바인딩하는 작업이 필요하다. 만약 biding하지 않으며 this가 undifined를 가르킨다.

return <EventPractice />

이 부분이 EventPractice 컴포넌트를 리턴하고, EventPractice 컴포넌트를 가서 render함수 안으로 가서 실행해주는데, 여기서 인풋태그와 버튼태그 그리고 h1태그를 리턴하여 돔을 주입하고, 클릭이 생기면 상태를 변경해준다고 이해했습니다. 그런데 상태를 변경해주는 과정을 이해하기가 어렵습니다.
button onClick={this.handleClick}>confirm
에 this는 뭐를 의미하는걸까요? this의 경우 호출부에 따라 결정된다고 하는데 여기서 호출부는 어디에 있는건지…
그럼 EventPractice에 쓰여진 this들의 경우 처음 호출부는 또 어딘건지…
답변 : render 아래 return에서 this.handleClick이 사용되고 있습니다.버튼을 클릭하면 호출이 되죠 말씀해주신 바와 같이 this는 호출부에 따라 주인객체를 가르키게 되는데 JSX return 하는 부분에서 this를 호출하면 window객체를 가르키게 됩니다. 그래서 해당 매소드를 bind 하여 컴포넌트를 가르키게 만든다고 생각하면 됩니다.

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

의 경우, bind로 보내주는 this에는 뭐가 담기게 되는 건가요?
답변: 여기서의 this는 해당 컴포넌트를 가르킵니다. this.handleClick을 this에 바인드 하는 겁니다.

this.handleClick = this.handleClick.bind(this);

this.handleClick을 호출할때 window를 가르키는데 풀어서 말하면 window.handleClick = window.handleClick(EventPractice) 이렇게 되는게 아니냐 라고 생각되실수 있는데

사실 그렇지 않습니다. 여기서 this.handleClick은 EventPractice.handleClick입니다. 내부에서 this를 불러냈기 때문입니다. 풀어서 이야기 하자면

EventPractice.handleChange = EventPractice.handleChange.bind(EventPractice);
EventPractice.handleClick = EventPractice.handleClick.bind(EventPractice);

이렇게 이해하시면 됩니다. (호출부가 EventPractice 내부이기 때문에 )

this는 책을 몇번을 봤는데도, 실제로 적용하는데 아직 오래걸릴 것 같다...

import React, { 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}></input>
                <input type="text" name="message" placeholder="writing space" value={this.state.message} onChange={this.handleChange}></input>
                <button onClick={this.handleClick}>확인</button>
            </div>
        );
    }
}

export default EventPractice;

그러므로 arrowFunction을 써주자! 일반함수는 자식이 종속된 객체를 this를 가르키지만, 화살표 함수는 자신이 종속된 인스턴스를 가리킴으로!

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

객체 안에서 key를 []로 감싸면 그 안에 넣은 레퍼런스가 가르키는 실제 값이 key값으로 사용된다.

const name = 'mia;
const object = {
	[name]:'value'
}

=> {
'variantKey':'value'
}

오류


username이 왜 undifined가 나온다. this.username으로 했기 때문에. 그래서 this.state.username!

import React, { Component } from "react";

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

    handleChange = (e) => {
        console.log(e.target.name)
        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>
                <input type="text" name="message" placeholder="writing space" value={this.state.message} onChange={this.handleChange} onKeyPress={this.handleKeyPress}></input>
                <button onClick={this.handleClick}>확인</button>
            </div>
        );
    }
}

export default EventPractice;

0개의 댓글