티스토리 뷰

728x90
반응형

오늘은 드디어 대망의 로그인 화면 구현하기를 정리하려 한다.

내용이 쉽지 않아서 정리하고도 이해가 잘 될지 걱정이 되지만 그래도 포기하지 않고 적어보려 한다.

이 부분은 한번에 이해가 쉽지 않기에 지속적인 반복으로 이해가 필요하다.

 

1. 메인 화면 디자인

// client > src > components > views > LandingPage > LandingPage.js
import React, { useEffect } from 'react';
import axios from 'axios';

function LandingPage() {

// 일부 생략

    return (
        <div style={{
            display: 'flex', justifyContent: 'center', alignItems: 'center', width: '100%', height: '100vh'
        }}>
            <h2>시작페이지</h2>
        </div>
    )
}

export default LandingPage

일단 전체적으로 가운데로 모아주는 작업으로 디자인 작업을 했다. 그러면 아래와 같이 헤더가 화면이 줄어도 가운데로 오는것을 볼 수 있다.

메인페이지 가운데 정렬한 화면

 

2. 로그인 화면 디자인

// client > src > components > views > LoginPage > LoginPage.js
import React from 'react';

function LoginPage(props) {
    
    return (
        <div style={{
            display: 'flex', justifyContent: 'center', alignItems: 'center', width: '100%', height: '100vh'
        }}>
            <form style={{display: 'flex', flexDirection: 'column'}}>
                <label>Email</label>
                <input type="email" />
                <label>Password</label>
                <input type="password" />
                <br />
                <button type="submit">Login</button>
            </form>
        </div>
    )
}

export default LoginPage

일단은 기존에 있는 스타일을 가져온 후 <form>태그로 로그인을 넣어준다. 로그인을 위해서는 이메일과 비밀번호 그리고 서버로 전달할 버튼까지 만든다. 이렇게 할 경우 현재 값을 입력할 수 없는 상태로 나온다.

localhost:3000/login화면 작업

 

3. value, onChange값 넣기

// client > src > components > views > LoginPage > LoginPage.js
import React, { useState } from 'react';
import { useDispatch } from 'react-redux';
import { loginUser } from '../../../_actions/user_action';

function LoginPage(props) {
    const [Email, setEmail] = useState("");
    const [Password, setPassword] = useState("");

    const onEmailHandler = (event) => {
        setEmail(event.currentTarget.value);
    }
    const onPasswordHandler = (event) => {
        setPassword(event.currentTarget.value);
    }
    
    return (
        <div style={{
            display: 'flex', justifyContent: 'center', alignItems: 'center', width: '100%', height: '100vh'
        }}>
            <form style={{display: 'flex', flexDirection: 'column'}}>
                <label>Email</label>
                <input type="email" value={Email} onChange={onEmailHandler} />
                <label>Password</label>
                <input type="password" value={Password} onChange={onPasswordHandler} />
                <br />
                <button type="submit">Login</button>
            </form>
        </div>
    )
}

export default LoginPage

input값에 직접 타이핑을 하기 위해서는 useState를 사용하여 상태를 변할 수 있는 값을 넣어준다. 또한 onChange이벤트를 통해서 현재 value값을 변경할 수 있다.

 

4. form submit 값 입력하기

// client > src > components > views > LoginPage > LoginPage.js
import React, { useState } from 'react';

function LoginPage(props) {

// 일부 생략

    const onSubmitHandler = (event) => {
        event.preventDefault();   
        console.log('Eamil', Email);
        console.log('Password', Password);
    }
    return (
		// 일부 생략
            <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 type="submit">Login</button>
            </form>
        </div>
    )
}

export default LoginPage

여기서 event.preventDefault값은 button이 submit을 할 경우 계속 리프레시가 되는 현상이 발생한다. 그래서 그 현상을 방지하고자 이 값을 넣은 후 값이 잘 들어오는지 console.log를 통해 테스트 해본다.

console.log로 value값이 잘 들어왔는지 확인한다

 

5. redux, action을 이용해서 로그인 기능을 완성하기

// client > src > components > views > LoginPage > LoginPage.js

// 일부 생략

import { useDispatch } from 'react-redux';
import { loginUser } from '../../../_actions/user_action';

function LoginPage(props) {
    // 일부 생략
    
    const dispatch = useDispatch();
    
    // 일부 생략

    const onSubmitHandler = (event) => {
        event.preventDefault();

        let body = {
            email: Email,
            password: Password
        }
        dispatch(loginUser(body))
            .then(response => {
                if(response.payload.loginSuccess) {
                    props.history.push('/') // 페이지 이동을 해줄 때
                } else {
                    alert('아이디 혹은 비밀번호 오류입니다. 다시 입력해주세요.');
                }
            })
        
    }
    return (
        // 일부 생략
    )
}

export default LoginPage

useDispatch를 이용하여 로그인이 성공할 경우 메인페이지로 이동을 한다.

 

// client > src > _actions > 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 => response.data)

    return {
        type: LOGIN_USER,
        payload: request
    }
}

로그인이 클라이언트에 값이 들어오면 서버로 보내 답을 받는다.

 

// client > src > _reducers > 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;
    }
}

user_action.js에서의 타입들이 계속 올 때마다 다른 조치를 취하기 위해 switch문법을 사용한다.

 

 

// client > src > _actions > types.js
export const LOGIN_USER = "login_user";

타입을 따로 묶어 관리를 할 수 있다.

 

여기까지 리덕스를 이용한 로그인 화면 구현하기였다.

아직 솔직히 다 이해는 못했다. 그래서 다시 재반복을 하면서 이해하고 거기서 생긴 궁금증을 추가적으로 넣을 예정이다.

앞으로 더욱더 견고한 내용으로 추가할 예정이다.

 

 

오늘의 코드 바로가기

728x90
반응형
댓글
250x250
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
글 보관함