TIL 48 | React 이벤트 핸들링 실습 (JS코드 React로 바꾸기)

meow·2020년 9월 1일
0

React

목록 보기
8/33

지난 번에 만들었던 인스타그램의 로그인 페이지를 React 라이브러리를 활용하여 구현해보고자 한다. HTML과 CSS까지 구현을 하고, CSS는 SCSS 확장자로 새로 정리를 해 둔 상태이다.

참고자료
리액트 공식문서 (조건부 렌더링)
리액트 공식문서 (폼)
React onChange Events (With Examples)

기존 JS 코드

순수 바닐라 자바스크립트로 짜여진 로그인 페이지의 함수이다. ID와 비밀번호 각각 validation check를 하고, 조건을 통과하면 버튼이 활성화되어 색이 변하며, 메인페이지로 이동하는 링크가 연결된다.
추가로 엔터키를 누를 경우 버튼을 클릭한 것과 동일한 결과를 보여줄 수 있도록 했다.

React로 바꾸는 과정

Render 되는 JSX

기존의 HTML과 크게 달라지는 부분은 없다. 아래 정석대로 코드를 조금 손봤다.

  • classclassName
  • </ >
  • JSX 최상위 요소의 className = 컴포넌트의 이름

이벤트 순서대로 코드 읽기

1. 인풋값 감지

<input value={this.state.id} onChange={this.handleIdChange} className="input_login" type="text" name="userID" placeholder="전화번호, 사용자 이름 또는 이메일" />
<input value={this.state.password} onChange={this.handlePwdChange} className="input_login" type="password" name="userPW" placeholder="비밀번호" />

onChange={} : onChange는 input에서 value가 변화하는 것을 감지한다. 따라서 인풋값이 변화할 때마다 (값이 입력될 때마다) {this.handleIdChange}{this.handlePwdChange}가 동작하게 된다.

2. this.state 변화

constructor() : 생성자 함수인 constructor 안에 초기화 할 값들을 넣는다. 처음에는 사용자 인풋이 없기 때문에 id와 password 값을 빈 스트링으로 설정했다.

handleIdChange & handlePwdChange : 1단계에서 인풋값이 변경이 되면 동작한다. 값이 변화할때마다 this.setState() 함수가 state를 업데이트한다.

3. Validation Check

canBeSubmitted() : this.state의 id와 password의 조건을 확인한다. 각각의 조건이 모두 true 값일때만 true를 return한다.

handleSubmit : canbeSubmited()가 false를 return한 경우, 즉 조건을 통과하지 못한 경우 서버에 request를 보내는 등의 디폴트 기능을 하지 않도록 한다.

참고자료

4. 버튼 활성화

canBeSubmitted() 가 true인 경우 button의 disabled class가 false로 바뀐다.

5. 메인 페이지로 연결

버튼에 onClick이벤트 발생시 Route 컴포넌트 안에 있는 /main 경로로 이동하게 된다. 또한 Enter Key Press 이벤트 발생시 버튼을 클릭한 것과 동일하게 된다.

완성된 React 전체 코드

import React from 'react';
import './Login.scss';
import { withRouter } from 'react-router-dom';


class Login extends React.Component {

    constructor() {
        
        super();
        
        this.state = {
            id: "",
            password: ""
        };
    }
    
    handleIdChange = evt => {
        this.setState({ id: evt.target.value });
    }

    handlePwdChange = evt => {
        this.setState({ password: evt.target.value })
    }

    handleSubmit = evt => {
        if (!this.canBeSubmitted()) {
            evt.preventDefault();
            return;
        }
    }
    
    canBeSubmitted() {
        const { id, password } = this.state;
        return id.includes('@') > 0 && password.length >= 5;
    }

    goToMain = () => {
        const { id, password } = this.state;
        console.log(`Signed up with id: ${id} password: ${password}`)
        this.props.history.push('main');
    }

    handleKeyPress = (e) => {
        if (e.key === "Enter") {
            this.goToMain();
        }
    }

    render() {
        const isEnabled = this.canBeSubmitted();
        return (
            <div className="Login">
                <div onSubmit={this.handleSubmit} onKeyPress={this.handleKeyPress} className="login_container">
                    <img alt="instagram_logo" className="logo_instagram" src="/img/logo_text.png" />
                    <input value={this.state.id} onChange={this.handleIdChange} className="input_login" type="text" name="userID" placeholder="전화번호, 사용자 이름 또는 이메일" />
                    <input value={this.state.password} onChange={this.handlePwdChange} className="input_login" type="password" name="userPW" placeholder="비밀번호" />
                    <button onClick={this.goToMain} id="btn_login" disabled={!isEnabled}>로그인</button>
                    <span className="button_forgot">비밀번호를 잊으셨나요?</span>
                </div>
            </div>
        )
    }
}

export default withRouter(Login);
profile
🌙`、、`ヽ`ヽ`、、ヽヽ、`、ヽ`ヽ`ヽヽ` ヽ`、`ヽ`、ヽ``、ヽ`ヽ`、ヽヽ`ヽ、ヽ `ヽ、ヽヽ`ヽ`、``ヽ`ヽ、ヽ、ヽ`ヽ`ヽ 、ヽ`ヽ`ヽ、ヽ、ヽ`ヽ`ヽ 、ヽ、ヽ、ヽ``、ヽ`、ヽヽ 🚶‍♀ ヽ``ヽ``、ヽ`、

0개의 댓글