LoginSignup
4
7

More than 3 years have passed since last update.

Laravel bladeからReactコンポーネント(Material UI)にバリデーションエラーメッセージを渡してみる

Posted at

地味だけど、割といいなと思ったTips。

blade側

errors='@json($errors->toArray())'がポイント。LaravelのValidationで返ってきた内容をjsonに変換している。
defaultValueは、エラー時に元の入力値を保持するために使用。

@extends('layouts.app')

@section('content')
    <div id="header"></div>
    <form method="POST" action="{{ route('login') }}">
        @csrf

        <div id="login" errors='@json($errors->toArray())' defaultValue='@json(['email'=>old('email')])'></div>

    </form>
    <script src="{{mix('js/app.js')}}" ></script>
@endsection

受け取るReactコンポーネント

import * as React from 'react';
import { render } from 'react-dom';
import PasswordField from '../atoms/PasswordField';
import EmailInputField from '../atoms/EmailInputField';
import SubmitButton from '../atoms/SubmitButton';
import { Grid } from '@material-ui/core';

type Props = {
    errors?: {
        email :string,
        password : string
    }
    defaultValue?: {
        email: string
    }
}

const Login: React.FC<Props> = ({ errors, defaultValue }) => (
    <div>
      // 中略
      <EmailInputField label="メールアドレス" errors={errors?.email} defaultValue={defaultValue?.email}/>
      <PasswordField label="パスワード" errors={errors?.password}/>
      <SubmitButton label="LOGIN"/>
      // 中略
    </div>
);

const Element = document.getElementById('login');
if(Element){
    const errors = Element.getAttribute('errors');
    const parsedErrors = errors && JSON.parse(errors);
    const defaultValue = Element.getAttribute('defaultValue');
    const parsedDefaultValue = defaultValue && JSON.parse(defaultValue);
    render(<Login errors={parsedErrors} defaultValue={parsedDefaultValue} />, 
            document.getElementById('login'));
}

bladeから受け取ったjsonをparseしているのはこの処理

あとはコンポーネントに渡してあげるだけ。

    const errors = Element.getAttribute('errors');
    const parsedErrors = errors && JSON.parse(errors);

エラー描画をするコンポーネント

helperTextはundefined許容なので、判定なしでerrorsを設定可能。

import React from 'react';
import TextField from '@material-ui/core/TextField';
import { InputAdornment } from '@material-ui/core';
import Mail from '@material-ui/icons/Mail';

type Props = {
  label: string;
  errors?: string;
  defaultValue?: string;
}

const EmailInputField: React.FC<Props> = ({ label , errors , defaultValue }) => (
  <div>
    <TextField id="email" name="email" label={label}
    error={(!!errors)?true:false}
    helperText={errors}
    defaultValue={defaultValue}
    />
  </div>
);

export default EmailInputField;
4
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
7