Я довольно неопытен с React и Redux Form, поэтому, пожалуйста, будьте терпеливы. У меня есть родительский компонент, в который я добавляю дочерний компонент (FormGenerator), который создает и возвращает поля формы избыточности. FormGenerator работает без проверок, но когда я пытаюсь добавить в него validate, избыточная форма выдает ошибки, из-за которых не знает, что делать с полями этого типа.
Отладчик показывает, что в hasError.js в избыточной форме разрешается тип :
$$ typeof: Symbol (react.forward_ref) и, следовательно, выдает ошибку неизвестного типа поля.
Любой совет, как обойти это, был бы очень признателен.
hasError.js формы Redux:
var getErrorKeys = function getErrorKeys(name, type) {
switch (type) {
case 'Field':
return [name, name + "._error"];
case 'FieldArray':
return [name + "._error"];
default:
throw new Error('Unknown field type');
}
};
Родительский компонент:
import React, { Component } from 'react';
import { connect } from 'react-redux';
import './AnswerQuestionnaire.scss';
import { reduxForm } from 'redux-form';
import { getQuestionnaireToTake, submitResponse } from '../../actions/questionnaires';
import FormGenerator from './FormGenerator';
import Spinner from '../../components/Spinner/Spinner';
const formName = "ResponseForm";
class AnswerQuestionnaire extends Component{
componentWillMount(){
this.props.getQuestionnaireById(this.props.match.params.id)
}
render(){
console.log(this.props)
if (this.props.questionnaire && this.props.questionnaire.questionnaireToTake){
return (
<div>
<form onSubmit={this.props.handleSubmit(this.props.submitResponse)}>
<FormGenerator data={this.props.questionnaire.questionnaireToTake} formName={formName}/>
<button type="submit">Submit</button>
</form>
</div>
)
} else {
return (
<Spinner/>
)
}
}
}
const mapStateToProps = (state) => {
return {
...state,
questionnaire : state.questionnaire
}
}
const mapDispatchToProps = (dispatch) => ({
getQuestionnaireById: (id) => { dispatch(getQuestionnaireToTake(id))},
submitResponse: (formValues) => { dispatch(submitResponse(formValues))}
})
export default reduxForm({
form: formName,
})(connect(mapStateToProps,mapDispatchToProps)(AnswerQuestionnaire));
Генератор форм:
import React, { Component } from 'react';
import InputField from "../../components/InputField/InputField";
import { connect } from 'react-redux';
import './AnswerQuestionnaire.scss';
import { Field, change, registerField } from 'redux-form';
import Select from '../../components/Select/Select';
import RadioButton from '../../components/RadioButton/RadioButton';
import CheckBox from '../../components/CheckBox/CheckBox';
import { required } from '../../utils/validators';
const stringToComponentMapper = {
RADIO: RadioButton,
CHECKBOX: CheckBox,
TEXT: InputField,
SELECT: Select
}
class FormGenerator extends Component{
constructor(props) {
super(props);
}
componentWillMount(){
//need to register and set values needed for submit and backend object, that we dont need to display on screen,
//this seems hacky but due to time constraints, I'm doing this like this.
if ( this.props.data){
const { questions } = this.props.data;
questions.map((item, index)=>{
let key = `answers.[${index}].id`;
this.props.dispatch(registerField("ResponseForm",key,Field)) ;
this.props.dispatch(change("ResponseForm",key,item.id)) ;
})
}
}
render(){
const { title, description, questions } = this.props.data;
if ( this.props.data){
return (
<div>
<h3>{title}</h3>
<h2>{description}</h2>
{questions.map((item, index)=>{
let fieldName = `answers.[${index}].answer`;
return(<div>
<Field key={index} validate={required} name={fieldName} component={stringToComponentMapper[item.type]} label={`Question #${index}: ${item.question}`} selectValues={item.answersAllowed}/>
</div>)
}
)}
</div>
)
} else {
return (
<div>
Looks like nothing here...
</div>
)
}
}
}
const mapStateToProps = (state) => {
return {
...state,
questionnaire : state.questionnaire
}
}
export default (connect(mapStateToProps)(FormGenerator));