로그인 페이지 만들기
LandingPage부터 하나하나 만들어보자.
우선 스타일부터 바꿔보자.
import React from 'react'
function LoginPage(){
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 onChange />
<label>Password</label>
<input type="password" value onChange />
<br />
<button>
Login
</button>
</form>
</div>
)
}
export default LoginPage
Email과 Password를 타이핑하고 싶지만 아직은 되지 않는다.
state를 정의하고 setState함수를 이용하여 값이 변했을 때 적용시켜 주면 된다.
import React, { useState } from 'react'
function LoginPage(){
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>
Login
</button>
</form>
</div>
)
}
export default LoginPage
이제 타이핑이 되는 것을 확인할 수 있다.
이제 form에 submit event를 적용시키면 된다.
그렇기 위해서는 button에 type을 submit이라 지정해주고 Axios를 이용해 서버에 데이터를 보내면 된다.
하지만 Redux를 사용하기 때문에 좀 더 작업이 필요하다.
redux를 사용하려면 action을 reducer에게 전달하여 nextState를 store에 업데이트해야 한다.
따라서 여러 작업을 해야 한다.
import Axios from 'axios'
import React, { useState } from 'react'
import { useDispatch } from 'react-redux'
import { loginUser } from '../../../_actions/user_action'
function LoginPage(){
const dispatch = useDispatch();
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();
let body = {
email: Email,
password: Password
}
dispatch(loginUser(body))
}
return(
<div style={{
display: 'flex', justifyContent: 'center', alignItems:'center',
width: '100%', height: '100vh'
}}>
<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
onsubmitHandler를 보면 Redux를 사용하지 않으면 Axios를 이용해 서버에 전달하기만 하면 된다.
하지만 Redux를 사용하기 위해서는 dispatch를 사용하여 store에 데이터를 업데이트해야 한다.
dispatch에게 action을 전달하면 되는데 이는 _action 디렉토리에 정의하면 된다.
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
}
}
types.js
export const LOGIN_USER = "login_user";
user_action이다. action에는 여러 타입이 있을 수 있기 때문에 type을 정의하여 관리하자.
서버에 request를 보낸 뒤 response를 받아 request 변수에 저장한 뒤 reducer에 보내는 것이다.
user_reducer
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;
}
}
현재 state는 비어있는 상태이고 스프레드 오퍼레이터를 사용하여 특정 객체를 새로운 객체로 복사하는 것을 의미한다.
즉, state를 복제하여 그대로 사용하겠다는 뜻이다. 그리고 loginSuccess에 전달받은 payload를 넣어 return 한다.
이제 서버를 키고 테스트해보면 다음과 같은 결과를 얻을 수 있다.
미리 가입해놓은 계정이 DB에 있고 똑같은 값을 입력하여 로그인을 성공적으로 완료했다.
action에서 서버에 보낸 request에 대한 response를 request에 저장하여 payload라 네이밍하여 return 했다.
그리고 reducer에서 next state를 만드는 것이다. 이제 로그인에 성공했으니 LandingPage로 보내보자.
import Axios from 'axios'
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("")
const onEmailHandler = (event) => {
setEmail(event.currentTarget.value)
}
const onPasswordHandler = (event) => {
setPassword(event.currentTarget.value)
}
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('Error')
}
})
}
return(
<div style={{
display: 'flex', justifyContent: 'center', alignItems:'center',
width: '100%', height: '100vh'
}}>
<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
props.history.push를 이용하여 로그인이 성공하면 LandingPage로 이동하게 하였다.