19

公式のSemantic UI Reactコンポーネントを使用して Web アプリケーションを作成しています。サインアップ ページに、電子メール フィールド、パスワード フィールド、およびパスワードの確認フィールドを含むフォームがあります。

import {Component} from 'react';
import {Button, Form, Message} from 'semantic-ui-react';
import {signUp} from '../../actions/auth';

class SignUp extends Component {
    constructor(props) {
        super(props);
        this.handleSubmit = this.handleSubmit.bind(this);
    }
    handleSubmit(e, {formData}) {
        e.preventDefault();

        //
        // Potentially need to manually validate fields here?
        //

        // Send a POST request to the server with the formData
        this.props.dispatch(signUp(formData)).then(({isAuthenticated}) => {
            if (isAuthenticated) {
                // Redirect to the home page if the user is authenticated
                this.props.router.push('/');
            }
        }
    }
    render() {
        const {err} = this.props;

        return (
            <Form onSubmit={this.handleSubmit} error={Boolean(err)}>
                <Form.Input label="Email" name="email" type="text"/>
                <Form.Input label="Password" name="password" type="password"/>
                <Form.Input label="Confirm Password" name="confirmPassword" type="password"/>

                {err &&
                    <Message header="Error" content={err.message} error/>
                }

                <Button size="huge" type="submit" primary>Sign Up</Button>
            </Form>
        );
    }
}

今では、フォーム検証アドオンを備えた通常のセマンティック UI ライブラリに慣れています。通常、別の JavaScript ファイルでそのようにルールを定義します。

$('.ui.form').form({
    fields: {
        email: {
            identifier: 'email',
            rules: [{
                type: 'empty',
                prompt: 'Please enter your email address'
            }, {
                type: 'regExp',
                value: "[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?",
                prompt: 'Please enter a valid email address'
            }]
        },
        password: {
            identifier: 'password',
            rules: [{
                type: 'empty',
                prompt: 'Please enter your password'
            }, {
                type: 'minLength[8]',
                prompt: 'Your password must be at least {ruleValue} characters'
            }]
        },
        confirmPassword: {
            identifier: 'confirmPassword',
            rules: [{
                type: 'match[password]',
                prompt: 'The password you provided does not match'
            }]
        }
    }
});

フォームを検証するためにセマンティック UI React コンポーネントを使用する同様の方法はありますか? ドキュメントを検索しても成功しませんでしたが、このセマンティック UI React ライブラリを使用した検証の例はないようです。

代わりに、関数で各フィールドを手動で検証する必要がありhandleSubmitますか? この問題を解決する最善の方法は何ですか? 助けてくれてありがとう!

4

9 に答える 9

0

これはかなり数年前のものであり、尋ねられた質問の完全な解決策ではないことを理解していますが、今日見ている人は、同じものを探していてこのスレッドに遭遇したので、これが役立つと思うかもしれません. Semantic-ui-react には私が見つけたフォーム検証はありませんが、フォーム検証エラーを表示する良い方法があります。検証は自分で行う必要があります。検証エラーがどのように表示されるかの例については、semantic-ui-react フォームのドキュメント ページを参照してください。また、成功メッセージを表示する機能もあります。状態に基づいてエラー メッセージを制御する方法のを作成しました。この例では、[性別エラーを表示] チェックボックスを使用して、性別入力のエラー メッセージを切り替えることができます。

于 2020-06-04T06:00:59.537 に答える
0

以下のコードは、基本的に状態を各コンポーネント名と関連する値に設定します。(IE、状態は {marketSide:buy, price:50, quantity:9} のように見えるかもしれません。また、フォームのエラー情報も状態に詰め込みます。yup のデフォルトの動作を利用して、検証スキーマで言及されていないフィールドを検証しません。 .

重要なポイント:

1) schema.validate(someObjectToValidate, yupProperties) (someObjectToValidate は this.state のみ) への呼び出しは、プロパティ オブジェクトとして {abortEarly:false} を渡す必要があります。これにより、yups の既定の動作がオーバーライドされ、単一のエラーが発生した場合に検証が停止されます。フォームのメッセージ コンポーネントがすべてのエラーをユーザーに表示するためです。

2) yup 検証が失敗した場合、yup は例外をスローするため、例外をキャッチし、関心のあるエラー情報を取得して、このエラーで状態を更新します。

3) setState は非同期であるため、状態が更新された後にのみ状態オブジェクトの検証が行われるように、this.setState(...) の「コールバック形式」を使用する必要があります。

4) yup 検証が成功した場合、エラーと errorPath 配列をクリアします。

5) これは簡単な解決策です。各レンダリングで errorPaths 配列を数回チェックしています。現在のソリューションを改善するには、2 つの配列ではなく、コンポーネントの名前をキーとする json オブジェクトに errorPath とエラー情報を格納することをお勧めします (2 配列 * N フィールド * N 潜在的なエラー = O(2n^2)パフォーマンス。

6) 長いスタイルの ' ' 表記を無視して、より短いetc スタイル<Form.Field control={Radio}>を使用できます。<Input>, <Button>, <Radio>,この構文は検証とは関係ありません。div も無視します。

import React, { Component } from 'react'
import { Button, Checkbox, Form, Input, Radio, Select, Message,  Label } from 'semantic-ui-react'
import * as yup from 'yup';


const options = [
  { text: 'buy', value: 'buy' },
  { text: 'sell', value: 'sell' },
]

class OrderEntryV3 extends Component {
  state = {
      errorPaths:[],
      errors:[]
  }

  constructor(props){
      super(props);
  }


  schema = yup.object().shape({
    quantity: yup.number().required().positive().integer(),
    price:  yup.number().required().positive(),
    marketSide: yup.string().required(),
    orderType : yup.string().required()
  });



  handleChange = (e, component) => {
      this.setState({[component.name]:component.value}, ()=>this.schema.validate(this.state, {abortEarly:false})
         .then(valid=>this.setState({errorPaths:[], errors:[]})) //called if the entire form is valid
         .catch(err=>this.setState({errors:err.errors, errorPaths: err.inner.map(i=>i.path) }))) //called if any field is invalid
    };


  render() {

    return (
<div id="oeform-content">
    <div id="oeform-left">
      <Form>
          <Form.Field  error={this.state.errorPaths.includes('marketSide')} name="marketSide" control={Select} label='Market side' options={options} placeholder='market side' onChange={this.handleChange}/>
          <Form.Field  error={this.state.errorPaths.includes('quantity')} type='number' name="quantity" control={Input} label='Quantity' placeholder='quantity' onChange={this.handleChange}/>

          <Form.Group>
              <label><b>Order type</b></label>  
        <Form.Field error={this.state.errorPaths.includes('orderType')} >
          <Radio
            label='market'
            name='orderType'
            value='market'
            checked={this.state.orderType === 'market'}
            onChange={this.handleChange}
          />
        </Form.Field>
        <Form.Field error={this.state.errorPaths.includes('orderType')}>
          <Radio
            label='limit'
            name='orderType'
            value='limit'
            checked={this.state.orderType === 'limit'}
            onChange={this.handleChange}
          />
        </Form.Field>
    </Form.Group>
        <Form.Field error={this.state.errorPaths.includes('price')} name='price' control={Input} type='number' label='Price' placeholder='price' onChange={this.handleChange}/>
        <Form.Field control={Button} disabled={!!this.state.errors.length}>Submit</Form.Field>
        <Message visible={!!this.state.errors.length} warning
        header='Please correct the following issues: '
        list={this.state.errors}/>
      </Form>
    </div>
    <div id="oeform-right">
        <p>{JSON.stringify(this.state)}</p>
    </div>
</div>
    )
  }
}

export default OrderEntryV3
于 2018-10-18T01:06:34.947 に答える