web-dev-qa-db-ja.com

redux-form:少なくとも1つのフィールドが無効な場合に送信ボタンを無効にする方法

Redux-formを使用して以下の単純なフォームをレンダリングしていますが、うまく機能しています。ここで、もう1つの状況で送信ボタンを無効にしたいと思います。Fieldのいずれかにエラーがある場合(つまり、meta.errorが設定されている場合)。

ドキュメントに目を通すことから、周囲の<form>がその<Field>コンポーネントにエラーがあるかどうかを知ることができないと思います。たぶん誰もがアイデアを持っている、disabled={hasErrors || submitting || pristine}を使用するのと同じくらい簡単にそれを解決する方法

const EditBlogEntryForm = ({ onSubmit, reset, handleSubmit,
                         pristine, submitting, ...rest }) => {
    console.log('rest: ', rest);
    return (
        <form onSubmit={handleSubmit(onSubmit)}>
            <div className="form-group">
                <Field name="title"
                    type="text"
                    component={renderField}
                    label="Titel"
                    className="form-control"
                    placeholder="Titel eingeben..." />
            </div>
            <div className="form-group">
                <Field name="text"
                    component={renderTextArea}
                    label="Text"
                    className="form-control"
                    placeholder="Textinhalt eingeben..." />
            </div>  
            <div className="form-group">
                <Field name="image"
                    type="text"
                    component={renderField}
                    label="Bild-URL:"
                    className="form-control"
                    placeholder="Bildadresse eingeben..." />
            </div>  
            <div>
                <button type="submit" className="btn btn-default"
                    disabled={submitting || pristine}>
                    Blogeintrag speichern
                </button>
                <button type="button" className="btn btn-default"
                    disabled={pristine || submitting}
                    onClick={reset}>
                    Formular leeren
                </button>
            </div>
        </form>
    );
};
14
Christof Kälin

SetStateコンポーネントごとにthis.propsを使用するだけで必要な状態を悪用しないでください。もう一度レンダリングされます

const {invalid} = this.props

return(
<button type="submit" className="btn btn-default"
     disabled={invalid|| submitting || pristine}>
     Blogeintrag speichern
 </button>)

その他のドキュメント: https://redux-form.com/6.0.0-alpha.4/docs/api/props.md/

21
masoud soroush

Reduxフォームはすでに多くのプロパティをフォームに渡します。 1つはinvalidです。これは、フィールド検証のいずれかが失敗したかどうかを判断し、送信を無効にするために使用しているものです。

https://redux-form.com/6.0.0-alpha.4/docs/api/props.md/

2
Nick Graham

できることは、Errorsと呼ばれる変数を用意することです。これは、API呼び出しにエラーが返されたときにtrueになります

 constructor(super) {
      this.state = {
         errors: false,
      }
 }

 componentWillReceiveProps(nextProps) {
     const that = this;
     if (nextProps.errors) {
        that.setState({errors: true})
     }    
 }

 <button type="submit" className="btn btn-default"
     disabled={this.state.errors || submitting || pristine}>
     Blogeintrag speichern
 </button>
2
Alastair

アラステアは私を正しい方向に向けてくれました(ありがとうございます!)。これは、ローカルUI関連の状態が実際に非常に役立つケースの1つだと思います。そのため、SFCをリアクションクラスにリファクタリングしました。そのクラスのconstructorcomponentWillReceivePropsは次のようになります。

constructor(props) {
    super(props);
    this.state = {
        errors: false
    };
}

componentWillReceiveProps(nextProps) {
    if (nextProps.invalid) {
        this.setState({errors: true});
    } else {
        this.setState({errors: false});
    }
}

this.state.errorsボタンを無効にすることは完全に機能しています。ご覧のとおり、invalid propフォームは常に未定義であり、フォームが有効な場合は再度trueに設定することを忘れないため、error propフォームredux-formを使用する必要がありました。さらに、答えでthis参照をthatにコピーした理由を知りません。まだ同じオブジェクトを指しているため、動作は変更されません。

0
Christof Kälin

可能性は、検証フィールドを使用することです。関数を定義する必要があります:

const required = value => (value ? undefined : 'Required')

そして、あなたのフィールドでこの関数を使用します:

           <div className="form-group">
                <Field name="title"
                    type="text"
                    component={renderField}
                    label="Titel"
                    className="form-control"
                    placeholder="Titel eingeben..."
                    validate={[required]}
                />
            </div>
0
morgane1806

react-redux-formライブラリを使用している場合、最終的にフォームのonUpdateイベントを使用してフォームの有効性状態をキャプチャし、このように非アクティブ化に使用できる内部状態変数を変更できますボタン。実行できることを示すサンプルコードを次に示します。

import React, { Component } from 'react';
import { Button, Modal, ModalHeader, ModalBody, Row, Label, Col } from 'reactstrap';
import { Control, LocalForm, Errors } from 'react-redux-form';

const required = (val) => val && val.length;

const maxLength = (len) => (val) => !(val) || (val.length <= len);

const minLength = (len) => (val) => (val) && (val.length >= len);

class CommentForm extends Component {

    constructor(props) {
        super(props);
        this.state = {
            isModalOpen: false,
            isFormInValid: true
        };
        this.toggleModal = this.toggleModal.bind(this);
    }

    toggleModal() {
        this.setState({
            isModalOpen: !this.state.isModalOpen
        })
    }

    handleSubmit(values) {
        console.log("Current state is: " + JSON.stringify(values));
        alert(JSON.stringify(values));
    }

    handleUpdate(form) {
        this.setState({ isFormInValid: !form['$form'].valid });
    }

    render() {
        return (
            <>
                <Button outline onClick={this.toggleModal}>
                    <span className="fa fa-pencil fa-lg"></span> Submit Comment
                </Button>
                <Modal isOpen={this.state.isModalOpen} toggle={this.toggleModal}>
                    <ModalHeader toggle={this.toggleModal}>Submit Comment</ModalHeader>
                    <ModalBody>
                        <LocalForm
                            onUpdate={(form) => this.handleUpdate(form)}
                            onSubmit={(values) => this.handleSubmit(values)}>
                            <Row className="form-group">
                                <Label htmlFor="author" md={12}>Your Name</Label>
                                <Col md={12}>
                                    <Control.text model=".author" id="author" name="author"
                                        placeholder="First Name" className="form-control"
                                        validators={{ required, minLength: minLength(3), maxLength: maxLength(15) }} />
                                    <Errors className="text-danger" model=".author" show="touched"
                                        messages={{ required: 'Required ', minLength: 'Must be greater than 2 characters', maxLength: 'Must be 15 characters or less' }} />
                                </Col>
                            </Row>
                            <Row className="form-group">
                                <Col md={12}>
                                    <Button type="submit" color="primary" disabled={this.state.isFormInValid}>Submit</Button>
                                </Col>
                            </Row>
                        </LocalForm>
                    </ModalBody>
                </Modal>
            </>
        );
    }
}
0
gil.fernandes