フリーランス 技術調査ブログ

フリーランス/エンジニア Ruby Python Nodejs Vuejs React Dockerなどの調査技術調査の備忘録

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

作成した画面

f:id:PX-WING:20200614093531p:plain