Auth Boiler Plate View with React,Redux - Login
01 May 2021 | Node.js ReactBoiler Plate with React,Redux - Login
Login View Page
Node.js 로 구현한 로그인 기능을 실질적으로 눈으로 확인하기 위해 view 페이지를 만든다
view는 react로 구현하고 상태관리는 redux를 이용한다
또, 빠른 실습을 위해 create-react-app으로 빌드한다
먼저, 간단한 로그인창을 만들고 input태그에 onChange 이벤트, form 태그에 onSubmit 이벤트를 걸어준다
onSubmit시 action을 dispatch한다
// LoginPage.js
import React, { useState } from 'react';
import { useDispatch } from 'react-redux';
import { loginUser } from '../../../_actions/user_action';
function LoginPage(props) {
const dispatch = useDispatch();
const [Email, setEmail] = useState('');
const [Password, setPassword] = useState('');
// Email onChange Event
const onEmailHandler = (e) => {
setEmail(e.currentTarget.value);
};
// Password onChange Event
const onPasswordHandler = (e) => {
setPassword(e.currentTarget.value);
};
// onSubmit Event
const onSubmitHandler = (e) => {
e.preventDefault();
// Request Body 생성
let body = {
email: Email,
password: Password,
};
// action에서 axios 요청을 실시하고 return값으로 응답을 받음
dispatch(loginUser(body)).then((response) => {
if (response.payload.loginSuccess) {
props.history.push('/');
} else {
alert('Login Fail!');
}
});
};
return (
<div>
<form
onSubmit={onSubmitHandler}
>
<label>Email</label>
<input type='email' value={Email} onChange={onEmailHandler} required />
<label>Password</label>
<input
type='password'
value={Password}
onChange={onPasswordHandler}
required
/>
<br />
<button type='submit'>Login</button>
</form>
</div>
);
}
export default LoginPage;
// user_action.js
import axios from 'axios';
export function loginUser(dataSubmit) {
// LoginPage에서 작성한 body로 axios 요청
const request = axios
.post('/api/users/login', dataSubmit)
.then((response) => {
return response.data;
});
// action의 payload에 response 데이터를 담는다
return {
type: 'LOGIN_USER',
payload: request,
};
}
// user_reducer.js
export default function (state = {}, action) {
switch (action.type) {
case 'LOGIN_USER':
return {
...state,
loginSuccess: action.payload,
};
default:
return state;
}
}
reducer는 기능별로 여러개가 나올것이므로 이 흩어져있는 reducer들을 모을 rootReducer가 필요하다
// _reducers/index.js
import { combineReducers } from 'redux';
import user from './user_reducer';
const rootReducer = combineReducers({
user,
// 이 곳에 reducer 추가
});
export default rootReducer;
redux 패키지의 combineReducers
메소드를 이용하여 각가의 reducer들을 모아준다
redux에서는 상태를 store라는 하나의 큰 저장소에서 관리하는데, store는 보통 index 등 패키지의 제일 앞단에 설치한다
앞으로 redux-thunk, redux-promise 등의 미들웨어를 사용할 예정이므로 store 생성시 이 미들웨어도 같이 끼워넣어 주어야한다.
store에 인자로 reducer를 넣어주는데, 이를 위해 react-redux 패키지의 Provider로 App 컴포넌트를 감싸준다
// index.js
import { createStore, applyMiddleware } from 'redux';
import { Provider } from 'react-redux';
import promiseMiddleware from 'redux-promise';
import ReduxThunk from 'redux-thunk';
import Reducer from './_reducers';
const createStoreWithMiddleware = applyMiddleware(
promiseMiddleware,
ReduxThunk
)(createStore);
ReactDOM.render(
<React.StrictMode>
<Provider
store={createStoreWithMiddleware(
Reducer,
window.__REDUX_DEVTOOLS_EXTENSION__ &&
window.__REDUX_DEVTOOLS_EXTENSION__()
)}
>
<App />
</Provider>
</React.StrictMode>,
document.getElementById('root')
);
window.머시기들은 redux-devtool을 사용하기 위한 환경변수이다
서버 구축시 테스트용으로 미리 넣어놓은 사용자로 로그인을 시도해본다
로그인 성공시 loginSuccess: true와 서버에서 만들어 보낸 JWT가 state에 잘 저장된 것을 볼 수 있다