提交Redux表格

时间:2017-11-16 13:44:58

标签: javascript reactjs react-redux redux-form

我有一个Redux表单,我试图将其作为向导分成几个子组件,如下所示:https://redux-form.com/7.0.4/examples/wizard/

但是,我无法正确地将表单连接到我的操作中以提交表单数据。该示例实际上将onSubmit方法传递到路由器的表单中,我不想这样做;相反,我想将我的表单连接到我的操作,然后将signUpUser方法传递给构成向导的三个组件中的最后一个。我目前的尝试是抛出两个错误:

Uncaught TypeError: handleSubmit is not a function

Warning: Failed prop type: The prop `onSubmit` is marked as required in `SignUp`, but its value is `undefined`.

我的原始表单组件工作正常,但相同的逻辑在新组件中不起作用。我认为这是一个范围问题,但不确定。我对React和Redux-Form比较新,所以我觉得这很难理解。想法?

新(破碎)组件:

import React, { Component, PropTypes } from 'react';
import { connect } from 'react-redux';
import * as actions from '../../actions';
import SignupFirstPage from './signupComponents/signupFirstPage';
import SignupSecondPage from './signupComponents/signupSecondPage';
import SignupThirdPage from './signupComponents/SignupThirdPage';

class SignUp extends Component {
    constructor(props) {
        super(props);
        this.nextPage = this.nextPage.bind(this);
        this.previousPage = this.previousPage.bind(this);
        this.state = {
            page: 1
        };
        this.handleFormSubmit = this.handleFormSubmit.bind(this);
    }
    nextPage() {
        this.setState({ page: this.state.page + 1 });
    }

    previousPage() {
        this.setState({ page: this.state.page - 1 });
    }

    handleFormSubmit(props) {
        this.props.signUpUser(props);
    }

    render() {
        const { handleSubmit } = this.props;
        const { page } = this.state;
        return (
            <div>
                {page === 1 && <SignupFirstPage onSubmit={this.nextPage} />}
                {page === 2 && (
                    <SignupSecondPage
                        previousPage={this.previousPage}
                        onSubmit={this.nextPage}
                    />
                )}
                {page === 3 && (
                    <SignupThirdPage
                        previousPage={this.previousPage}
                        onSubmit={handleSubmit(this.handleFormSubmit.bind(this))}
                    />
                )}
                <div>
                    {this.props.errorMessage &&
                        this.props.errorMessage.signup && (
                            <div className="error-container">
                                Oops! {this.props.errorMessage.signup}
                            </div>
                        )}
                </div>
            </div>
        );
    }
}

function mapStateToProps(state) {
    return {
        errorMessage: state.auth.error
    };
}

SignUp.propTypes = {
    onSubmit: PropTypes.func.isRequired
};
export default connect(mapStateToProps, actions)(SignUp);

新的子组件(最后一个):

import React from 'react';
import { Field, reduxForm } from 'redux-form';
import validate from './validate';
import renderField from '../../renderField';

const SignupThirdPage = props => {
    const { handleSubmit, pristine, previousPage, submitting } = props;
    return (
        <form onSubmit={handleSubmit}>
            <Field
                name="password"
                type="password"
                component={renderField}
                label="Password"
            />
            <Field
                name="passwordConfirm"
                type="text"
                component={renderField}
                label="Confirm Password"
            />
            <div>
                <button
                    type="button"
                    className="previous btn btn-primary"
                    onClick={previousPage}>
                    Previous
                </button>
                <button
                    className="btn btn-primary"
                    type="submit"
                    disabled={pristine || submitting}>
                    Submit
                </button>
            </div>
        </form>
    );
};
export default reduxForm({
    form: 'wizard', //Form name is same
    destroyOnUnmount: false,
    forceUnregisterOnUnmount: true,
    validate
})(SignupThirdPage);

旧组件:

import React, { Component } from 'react'
import { connect } from 'react-redux'
import { Field, reduxForm } from 'redux-form'
import * as actions from '../../actions'
import { Link } from 'react-router';

const renderField = ({ input, label, type, meta: { touched, error, warning } }) => (
    <fieldset className="form-group">
        <label htmlFor={input.name}>{label}</label>
        <input className="form-control" {...input} type={type} />
        {touched && error && <span className="text-danger">{error}</span>}
    </fieldset>
)

class SignUp extends Component {

    constructor(props)
    {
        super(props);

        this.handleFormSubmit = this.handleFormSubmit.bind(this);
    }

    handleFormSubmit(props) {
        // Sign user up
        this.props.signUpUser(props);
    }

    render() {
        const { handleSubmit } = this.props;

        return (
            <div className="form-container">
                <form onSubmit={handleSubmit(this.handleFormSubmit.bind(this))}>
                    <Field name="firstName" component={renderField} type="text" label="First Name" />
                    <Field name="lastName" component={renderField} type="text" label="Last name" />
                    <Field name="email" component={renderField} type="email" label="Email" />
                    <Field name="company" component={renderField} type="text" label="Company"/>
                    <Field name="password" component={renderField} type="password" label="Password" />
                    <Field name="password_confirmation" component={renderField} type="password" label="Password Confirmation" />
                    <div>
                        {this.props.errorMessage && this.props.errorMessage.signup &&
                            <div className="error-container">Oops! {this.props.errorMessage.signup}</div>}
                    </div>
                    <button type="submit" className="btn btn-primary">Sign Up</button>
                </form>
            </div>
        );
    }
}

function validate(values) {
    let errors = {}

    if (values.password !== values.password_confirmation) {
        errors.password = 'Password and password confirmation don\'t match!'
    }

    return errors
}

function mapStateToProps(state) {
    return {
        errorMessage: state.auth.error
    }
}

SignUp = reduxForm({ form: 'signup', validate })(SignUp);
export default connect(mapStateToProps, actions)(SignUp);

2 个答案:

答案 0 :(得分:1)

答案:

Redux-Form说:

  

您可以通过恰当命名的值访问表单的输入值   由redux-form Instance API提供的prop。

这是它的工作原理:由于我的组件已连接,我可以在其道具中访问我的操作。因此,在我的render方法中,我可以简单地将signUpUser方法传递给子组件,如下所示:

<SignupThirdPage
    previousPage={this.previousPage}
    signingUp={this.signingUp}
    onSubmit={values => this.props.signUpUser(values)}
/>

答案 1 :(得分:1)

您的问题是这个

Containers:
 api:
  Image: docker-registry.default.svc:5000/registry/console@sha256:8a...02
 console:
  Image: docker-registry.default.svc:5000/registry/console@sha256:8a...02

如果仔细查看代码,您会发现函数{page === 3 && ( <SignupThirdPage previousPage={this.previousPage} onSubmit={handleSubmit(this.handleFormSubmit.bind(this))} /> )} 不存在。

我认为您的意思是写这个:

handleSubmit