初心者のプログラミング日記

プログラミング初心者の日記

プログラミングに関することを書いていきます。

Laravel+Reactでバリデーションエラーを表示する。

今回はLaravel+ReactでLaravelでバリデーションを行い、そのエラーメッセージをReactで表示してみたいと思います。

とりあえず、分かりやすいようにReact側では新規登録の画面を作っていきます。

import React from 'react';
import ReactDOM from 'react-dom';
import axios from 'axios';



class Example extends React.Component{
    constructor(){
        super();
        this.state={
            email:'',
            name: '',
            password:'',
            error:[]
        }
        this.setemail=this.setemail.bind(this);
        this.setname=this.setname.bind(this);
        this.setpassword=this.setpassword.bind(this);
        this.onSubmit = this.onSubmit.bind(this);
    }

    setemail(e){
        this.setState({email:e.target.value});
    }

    setname(e){
        this.setState({name: event.target.value});
    }

    setpassword(e){
        this.setState({password:e.target.value});
    }

    onSubmit(e){
        e.preventDefault();
        const data = new FormData();
        data.append('email',this.state.email ? this.state.email: '');
        data.append('name', this.state.name ? this.state.name : '');
        data.append('password',this.state.password ? this.state.password: '')

        axios.post('api/register',data)
              .then(res=>{})
              //.catch(e=>this.setState({error:e.response.data.errors}))
              .catch(e => { console.log(e.response.data.errors) })
        


    }
    render(){
        return(
            <div className='register'>
            <div className='register-card'>
                <h1>新規登録</h1>
                <form onSubmit={this.onSubmit} encType="multipart/form-data">
                <ul>
                    <li><label>メールアドレス</label></li>
                    <li><input type="email" value={this.state.email} onChange={this.setemail}/></li>

                    <li><label>名前</label></li>
                    <li><input type="text" value={this.state.name} onChange={this.setname}/></li>

                    <li><label>パスワード</label></li>
                    <li><input type="password" value={this.state.password} onChange={this.setpassword}/></li>

                    <li className='logincheck'><input type="checkbox"/>ログインを継続する</li>
                    <button type="submit">登録</button>
                </ul>
                </form>
                <p>名前:{this.state.name}</p>
               <p>メールアドレス:{this.state.email}</p>
               <p>パスワード:{this.state.password}</p>
               <p>{this.state.error.email}</p>
            </div>
        </div>
        );
    }
}

export default Example;

if (document.getElementById('example')) {
    ReactDOM.render(<Example />, document.getElementById('example'));
}

こんな感じでAPIを使ってデータをコントローラーに送ります。
e.response.data.errorsでバリデーションエラーを取得できます。

次にコントローラを書いていきます。

<?php

namespace App\Http\Controllers;

use App\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use App\Http\Requests\RegisterRequest; //追加



class UserController extends Controller
{
    public function register (RegisterRequest $request){
        Log::debug($request);

        $user=new User;
        $user->name=$request->name;
        $user->email=$request->email;
        $user->password= Hash::make($request->password);
        $user->save();

        return view('welcome');
    }
}

今回はFormRequestクラスを使っているので書き方が少し異なっています。
FormRequestクラスを使う場合は
public function register (Request $request)
ではなく
public function register (RegisterRequest $request)
このように作ったFormRequestクラスを使います。
ここの処理はFormRequestクラスで弾かれた場合実行されません。

次にFormRequestクラスを作っていきます。

artisan make:request TRegisterRequest

中身を書き換えていきます。

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Contracts\Validation\Validator;
use Illuminate\Http\Exceptions\HttpResponseException;

class RegisterRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true; //デフォルトはfalseなので変更
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'name' => ['required', 'string', 'max:255'],
            'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
            'password' => ['required', 'string', 'min:8', 'confirmed'],
        ];
    }

    protected function failedValidation( Validator $validator ){
        $response['errors']  = $validator->errors()->toArray();
        throw new HttpResponseException( response()->json( $response, 422 ));
    }
}

public function authorizeの戻り値をtrueにして許可します。
public function rulesにはバリデーションルールを書いていきます。
protected function failedValidation( Validator $validator )はバリデーションエラーをjsonで返すためにオーバーライドしています。
ここをオーバーライドしないとHTMLを返してしまうので、React側でバリデーションエラーを取得できません。

これでReact側でバリデーションエラーを取得できるので、後は好きなように使ってください。
f:id:nasubiFX:20200517150831p:plain