使用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)
)
);
答案 0 :(得分:2)
mapStateToProps
是connect
的第一个参数,mapDispatchToProps
是第二个参数。尝试调换订单:
connect(
mapStateToProps,
mapDispatchToProps
)(CreateStudentsForm)