调度不起作用

时间:2019-05-07 18:46:03

标签: reactjs forms react-redux

客观

使用react-redux和revalidate设置由用户控制的动态表单,以对我的表单进行验证检查。

问题:

由于我的表单是动态的,因此我需要进行动态验证。为此,我需要将表单数据作为道具传递给我的组件,该组件可用作revalidate的validate函数中的第二个参数

我的方法

要做到这一点,我要等到组件被安装,构建表单,将其传递给redux之后,再将状态映射到props。当用户添加更多行时,我将更新状态,然后组件将呈现。我将使用shouldComponentUpdate()来避免任何渲染循环。

错误

我的错误是关于调度。当我尝试运行分派(它将把表单传递给redux)时,出现Dispatch is not a function错误。

我对connect()感到不舒服,因为我必须用它包装redux以及firebase。这种语法确实让我感到困惑。

问题

我相信如何在使用HOC的地方导出组件的问题,例如withFirebase,Redux和Connect。一路走来,我失去了连接的范围。有人可以告诉我我在做什么错吗?

组件

import React, { Component } from "react";
import { reduxForm, Field } from "redux-form";
import { Container, Form, Col, Button } from "react-bootstrap";
import MaterialIcon from '../../material-icon/materialIcon';
import { withFirestore } from "react-redux-firebase";
import { connect } from "react-redux";
import TextInput from "../../forms/textInput";
import { combineValidators, isRequired } from "revalidate";
import { setupStudentForm } from '../../../store/actions/students';


const validate = (values, ownprops) => {
    // Will be passing in validation rules, once form is apssed in with props via mapStateToProps.
}

export class CreateStudentsForm extends Component {
    // Using constrcutor so componentDidMount() can render() cann access variables
    constructor(props) {
        super(props);
        this.state = {
            rows: 2,
        }
        this.formArray = [];
        this.form = null;
    }

    componentDidMount() {
        // Once component is rendered, setup form and send to redux
        for (let i = 1; i !== this.state.rows + 1; i++) {
            let firstNameField = {
                fieldName: `firstName${i}`,
                label: 'First Name',
                required: true,
                type: "text",
            }
            let lastNameField = {
                fieldName: `lastName${i}`,
                label: 'Last Name',
                required: true,
                type: "text",
            }
            this.formArray.push([firstNameField, lastNameField]);
        }
        this.props.setupStudentFormHandler(this.formArray);
    }

    // Ensure we do not get stuck in render loop
    shouldComponentUpdate(nextProps, nextState){
        if(nextProps !== this.props){
            return true
        } else {
            return false
        }
    }

    render() {
        // Allows user to add another row
        const addRow = () => {
            this.setState({
                rows: this.state.rows + 1
            })
        }

        // Map through form array and create template
        if (this.formArray) {
            let form = this.formArray.map((field, index) => {
                return (
                    <Form.Row key={index} className="animated fadeIn">
                        <Col xs={5}>
                            <Form.Group className="mb-0 noValidate">
                                <Field
                                    label={field[0].label}
                                    attempt={this.props.attempt}
                                    name={field[0].fieldName}
                                    type={field[0].type}
                                    component={TextInput}
                                />
                            </Form.Group>
                        </Col>
                        <Col xs={5}>
                            <Form.Group className="mb-0 noValidate">
                                <Field
                                    label={field[1].label}
                                    attempt={this.props.attempt}
                                    name={field[1].fieldName}
                                    type={field[1].type}
                                    component={TextInput}
                                />
                            </Form.Group>
                        </Col>
                        <Col xs={2}>
                            <MaterialIcon icon="delete" className="mt-4" />
                        </Col>
                    </Form.Row>
                )
            })
        }
        return (
            <Container>
                {this.form}
                <Button variant="outline-success" onClick={addRow}>Add Another Student</Button>
            </Container>
        )
    }
}

const mapStateToProps = state => {
    return {
        // Get access to student state which will have form
        studentForm: state.students 
    };
  };

  const mapDispatchToProps = dispatch => {
    return {
        //Send formArray to redux
        setupStudentFormHandler: (form) => dispatch(setupStudentForm(form))  
    };
  };


export default withFirestore(
    reduxForm({
        form: "createStudents", validate
    })(connect(
            mapDispatchToProps,
            mapStateToProps
        )(CreateStudentsForm)
    )
);

1 个答案:

答案 0 :(得分:2)

mapStateToPropsconnect的第一个参数,mapDispatchToProps是第二个参数。尝试调换订单:

connect(
  mapStateToProps,
  mapDispatchToProps
)(CreateStudentsForm)