로그인 페이지 코드를 작성하기에 앞서 React에 대해 더 알아야 할 부분이 있다.

 

React와 React Hooks

먼저 React Component에 대해 살펴보면, 아래 표와 같이 Class Component와 Functional Component로 구분하여 비교할 수 있다. 

React Component

 

Class Component는 Functional Component 보다 더 많은 기능을 사용할 수 있다.

그렇다면 Functional Component에서는 어떠한 기능들을 사용할 수 없는지 알아 볼 필요가 있다.

 

 

React Component Lifecycle

 

위 이미지는 Class Component를 사용하여 React 페이지를 시작할 때 실행되는 Lifecycle이다. 

위 메소드들은 Functional Component에서 사용할 수 없었기 때문에 이전에는 대부분 Class Component를 사용했다고 한다.

그러다 React 16.8에서 발표된 Hooks을 통해 Functional Component에서도 Class Component에서만 사용할 수 있었던 메소드들을 사용할 수 있게 되었다.  

 

↓참고 사이트

https://projects.wojtekmaj.pl/react-lifecycle-methods-diagram

https://www.zerocho.com/category/React/post/579b5ec26958781500ed9955

 

 

React Hooks을 통해 Functional Component에서 state을 지정할 수 있게 되었고,

componentDidMount(useEffect) 등의 Class Component 기능들을 사용할 수 있게 된 것을 위의 코드 예시를 통해 알 수 있다.

 

요즘 새롭게 React로 개발하는 개발자들은 React Hooks을 많이 사용한다고 하여 John Ahn님의 노드 리액트 기초 강의에서는 React Hooks을 사용하여 진행된다.

 

 

 

Login Page

 

// LoginPage.js

import React, { useState } from 'react'

import { withRouter } from 'react-router-dom';


function LoginPage() {

    const [Email, setEmail] = useState("")
    
    const [Password, setPassword] = useState("")
    
    const onEmailHandler = (event) => {
    
    	setEmail(event.currentTarget.value)
    
    }
    
    const onPasswordHandler = (event) => {
    
    	setPassword(event.currentTarget.value)
    
    }
    
    const onSubmitHandler = (event) => {

	event.preventDefault(); //페이지 refresh를 막아줌
    
    	console.log("Email", Email)
    
    	console.log("Password", Password)
    
    }


	return (
    	    <div style = {{
        	
            	display: 'flex', justifyContent: 'center', alignItems: 'center', width: '100%', height: '100vh'
    	    
            }}>
            
                <h2>LoginPage</h2>
        
        	<form style = {{ display: 'flex', flexDirection: 'column' }}
            
            	    onSubmit={onSubmitHandler}
            
                >
            
            		<label>Email</label>
                
                	<input type="email" value={Email} onChange={onEmailHandler} />
                
                	<label>Password</label>
                
                	<input type="password" value={Password} onChange={onPasswordHandler} />
                
                	<br />
                
                	<button>
                
                		Login
                    
                	</button>
                
            	</form>
            
	    </div>

	)
}

export default withRouter(LoginPage)

 

여기서 withRouter를 사용하는 이유는 나중에 props.history.push('/'); 와 같이 페이지를 이동할 때 필요하기 때문이다.

 

 

이제 터미널 창에 npm run dev를 입력해서 실행시키고 localhost:3000/login으로 이동하면 다음과 같은 화면이 뜬다.

LoginPage (1)

 

 

onEmailHandler와 onPasswordHandler에서 현재 입력된 값(event.currentTarget.value)을 각각 setEmail, setPassword를 통해 Email과 Password에 저장해줌으로써 input 필드에 값이 반영되고, 로그인 버튼을 눌러보면 입력된 이메일과 패스워드의 값이 console에 찍히는 것을 확인할 수 있다. 

 

LoginPage (2)

 

 

 

이제 이 값들을 백엔드로 보내기 위해서는 Axios를 사용하면 더 간단한데 John Ahn님은 교육적 차원에서 Redux를 사용하여 코드를 작성했다.

//Axios 사용

import Axios from 'axios';


function LoginPage() {

    const onSubmitHandler = (event) => {
    
        event.preventDefault();
        
        
        let body = {
        
            email: Email,
            
            password: Password
            
        }
        
        Axios.post('/api/users/login'), body)
        
        .then(response => {
        
        	//로그인 실패, 성공에 따른 처리 작업
            
        })
        
    }

}

 

//Redux 사용

import { useDispatch } from 'react-redux';

import { loginUser } from '../../../_actions/user_action';


function LoginPage() {

    const dispatch = useDispatch();
    

    const onSubmitHandler = (event) => {
    
        event.preventDefault();
        
        
        let body = {
        
            email: Email,
            
            password: Password
            
        }
        
        dispatch(loginUser(body)) //loginUser Action에 body를 넘겨줌
       
    }

}

 

LoginPage.js에서 작성한 loginUser Action을 만들기 위해 _actions 폴더 안에 user_action.js 파일을 생성하고 다음 코드를 작성한다. 

//user_action.js

import axios from 'axios';

import { LOGIN_USER } from './types';


export function loginUser(dataToSubmit) {

    const request = axios.post('/api/users/login'), dataToSubmit)
        
        .then(response => reponse.data)


    return { //reducer로 넘겨준다.
    
        type: LOGIN_USER, 
        
        payload: request
        
    }

}

 

그리고 별도로 type을 관리해주는 types.js를 _actions 폴더 안에 생성한다.

//types.js

export const LOGIN_USER = "login_user";

 

Reducer 부분은 _reducers 폴더 안에 user_reducer에 작성하면 된다.

//user_reducer.js

import { LOGIN_USER } from '../_actions/types';


export default function (state = {}, action) {

	switch (action.type) {
    
    		case LOGIN_USER:
        
        		return { ...state, loginSuccess: action.payload }
            
        		break;
            
        	default:
        
        		return state;
	}

}

 

마지막으로 _reducers 폴더 안에 있는 index.js에서 주석처리 했던 import user 부분과 user의 주석 처리를 제거하면 된다.

 

 

다시 이메일과 패스워드를 입력하고, 로그인 버튼을 누르고나서 Redux Extension에서 확인해보면 성공적으로 로그인된 것을 확인할 수 있다.

 

이제 LoginPage.js에서 로그인 성공과 실패 시에 처리해주는 코드를 작성하면 된다. 

//LoginPage.js의 onSubmitHandler()


function LoginPage(props) { //props 넣어줘야함

    const onSubmitHandler = (event) => {
    
        event.preventDefault();
        
        
        let body = {
        
            email: Email,
            
            password: Password
            
        }
        
        dispatch(loginUser(body))

    	.then(response => {
    
	    if(response.payload.loginSuccess) {
        
		props.history.push('/') //로그인 성공 시 LandingPage로 이동
            
            }
        
            else {
        
        	alert('Error')
            
            }
        
    	})
        
    }

}

 

작성한 코드들을 저장하고 실행시켜주면 로그인 성공 시 랜딩 페이지로 이동하는 것을 확인할 수 있다.

LoginPage (3)

 

LandingPage

 

 

 

실행시키다 발생한 에러

발생한 에러

 

해결 방법

에러 해결

자동으로 생성된 express를 import하는 코드를 지우니까 해결되었다.

 

+ Recent posts