Отправка не функция - PullRequest
1 голос
/ 07 мая 2019

Цель

Настройка динамической формы, контролируемой пользователем, с использованиемact-redux и revalidate для запуска проверок в моей форме.

Проблема:

Поскольку моя форма является динамической, мне нужно выполнить динамические проверки.Для этого мои данные формы должны быть переданы как компонент моего компонента, который можно использовать в качестве второго аргумента в функции проверки от revalidate

Мой подход

Для этогоЯ жду, пока компонент будет смонтирован, создаю форму, передаю ее в Redx, а затем сопоставлю состояние с реквизитом.Поскольку пользователь добавляет больше строк, я буду обновлять состояние, а затем компонент будет визуализироваться.Я буду использовать shouldComponentUpdate (), чтобы избежать циклов рендеринга.

Ошибка

Моя ошибка связана с отправкой.Когда я пытаюсь запустить диспетчеризацию (которая передаст форму в редукс), я получаю ошибку Dispatch is not a function.

Я не чувствую себя комфортно с connect(), так как я должен обернуть его как реверсом, так и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 Ответ

2 голосов
/ 07 мая 2019

mapStateToProps - первый аргумент connect, mapDispatchToProps - второй.Попробуйте поменять порядок:

connect(
  mapStateToProps,
  mapDispatchToProps
)(CreateStudentsForm)
...