ReactHooksでログイン画面を実装する
はじめに
- 前回ログイン画面を作成したので、今度はログイン画面の実装をする
px-wing.hatenablog.com px-wing.hatenablog.com
Reactでログイン画面を実装する
-front側
import React,{useState, useContext } from 'react'
import {
BrowserRouter as Router,
Redirect,
Link
} from 'react-router-dom'
import axios from 'axios'
import AppContext from '../contexts/AppContext'
import { LOGIN } from '../actions'
import {Form, Button, Modal, Col} from 'react-bootstrap'
import './siginin.css'
import { Formik } from 'formik'
import * as yup from 'yup'
const Login = () => {
const {state, dispatch } = useContext(AppContext)
const [show, setShow] = useState(false);
const [apiState, setApiState] = useState({success: '',error: '',token: ''});
const handleClose = () => {
setShow(false)
};
const handleShow = () => setShow(true);
const schema = yup.object({
userName: yup.string().matches(/^[a-zA-Z0-9!-/:-@¥[-`{-~]*$/, 'ユーザー名は半角英数字と記号のみ').min(4,'ユーザー名は最低4文字です').required('ユーザー名を入力してください。'),
mailAddress: yup.string().email('正しいメールアドレスを入力してください').required('メールアドレスを入力してください。'),
password: yup.string().matches(/^[a-zA-Z0-9!-/:-@¥[-`{-~]*$/, 'ユーザー名は半角英数字と記号のみ').min(8,'パスワードは最低8文字です').required('パスワードを入力してください。'),
});
const loginAuth = async (values) => {
await axios.post('https://www.hogehoge.com/backend/api/login',values)
.then(res =>{
setApiState(res.data)
dispatch({
type: LOGIN,
user: res.data.user
})
});
handleShow()
};
return (
<Formik
validationSchema={schema}
onSubmit={(values, actions) => {
loginAuth(values);
}}
initialValues={{ userName: '', mailAddress: '',password: ''}}
>
{
({handleSubmit, handleChange, handleBlur, values, errors, touched}) => (
<>
<h4>ログイン</h4>
<Form noValidate onSubmit={handleSubmit}>
<Form.Group controlId="formGroupName">
<Form.Label>ユーザー名</Form.Label>
<Form.Control name="userName" type="text" placeholder="Enter name" value={values.userName} onBlur={handleBlur} onChange={handleChange} isInvalid={!!(touched.userName && errors.userName)}/>
<Form.Control.Feedback>OK!</Form.Control.Feedback>
<Form.Control.Feedback type="invalid">{errors.userName}</Form.Control.Feedback>
</Form.Group>
<Form.Group controlId="formGroupEmail">
<Form.Label>メールアドレス</Form.Label>
<Form.Control name="mailAddress" type="email" placeholder="Enter email" value={values.mailAddress} onBlur={handleBlur} onChange={handleChange} isInvalid={!!(touched.mailAddress && errors.mailAddress)}/>
<Form.Control.Feedback>OK!</Form.Control.Feedback>
<Form.Control.Feedback type="invalid">{errors.mailAddress}</Form.Control.Feedback>
</Form.Group>
<Form.Group controlId="formGroupPassword">
<Form.Label>パスワード</Form.Label>
<Form.Control name="password" type="password" placeholder="Password" value={values.password} onBlur={handleBlur} onChange={handleChange} isInvalid={!!(touched.password && errors.password)}/>
<Form.Control.Feedback>OK!</Form.Control.Feedback>
<Form.Control.Feedback type="invalid">{errors.password}</Form.Control.Feedback>
</Form.Group>
<div className='text-center'>
<Button variant="primary" type="submit">ログイン</Button>
</div>
</Form>
<Modal show={show} onHide={handleClose}>
<Modal.Header closeButton>
<Modal.Title>ログイン{apiState.success != '' ? '完了' : 'エラー'}</Modal.Title>
</Modal.Header>
<Modal.Body>
{apiState.success}
{apiState.error}
</Modal.Body>
<Modal.Footer>
<Link to="/bmi">
<Button variant="secondary" onClick={handleClose}>
Close
</Button>
</Link>
</Modal.Footer>
</Modal>
</>
)}
</Formik>
)
}
export default Login
- action.jsに追記する
export const LOGIN = 'LOGIN'
- reducers/user.jsの処理内容
import {
CREATE_USER,
LOGIN,
LOGOUT
} from '../actions'
const user = (state ={}, action) => {
switch (action.type) {
case CREATE_USER:
state = {
userName: action.user.user_name,
birthDay: action.user.birth_day,
sex: action.user.sex,
mailAddress: action.user.stmail_address,
token: action.user.token
}
return state
case LOGIN:
state = {
userName: action.user.user_name,
birthDay: action.user.birth_day,
sex: action.user.sex,
mailAddress: action.user.stmail_address,
token: action.user.token
}
return state
case LOGOUT:
return {}
default:
return state
}
}
export default user
作成した画面
