redux-form:如果至少有一个Field无效,如何禁用提交按钮?

时间:2017-05-03 19:33:51

标签: reactjs redux react-redux redux-form

我使用redux-form渲染以下简单的表单,它运行良好。现在,我想在另外一种情况下禁用提交按钮:如果Field中的任何一个有错误(即设置了meta.error)。

从lokking到文档,我想周围的<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>
    );
};

7 个答案:

答案 0 :(得分:18)

请勿使用this.props滥用您需要的状态 对于每个setState组件,将再渲染一次

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/

答案 1 :(得分:2)

你应该做的只是有一个名为Errors的变量,一旦你的api调用返回错误就会成立

 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 :(得分:1)

Redux表单已经将许多属性传递给该表单。一个是invalid。这就是我用来确定任何字段验证是否失败然后禁用提交的原因。

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

答案 3 :(得分:0)

阿拉斯泰尔向我指出了正确的方向(谢谢!)。我想这是本地UI相关状态实际上非常有用的情况之一。所以我将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形式的redux-form,因为它的error道具总是未定义的,如果表格有效,不要忘记再将它设置为true。此外,我不知道,为什么您在答案中将this引用复制到that。它不会改变任何行为,因为它仍然指向同一个对象。

答案 4 :(得分:0)

一种可能性是使用验证字段。您需要定义一个函数:

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>

答案 5 :(得分:0)

如果您正在使用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>
            </>
        );
    }
}

答案 6 :(得分:0)

这是Masoud Soroush答案的更新。

仅检查无效道具就足够了。

const {invalid} = this.props

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

注意:仅当您传递了返回承诺的onSubmit函数时,才使用提交道具。在诺言得到解决或拒绝之前,一切都会如此。