Я создаю компонент, который позволит пользователям приглашать своих друзей.
Спецификация компонента заключается в том, что он будет иметь несколько форм ввода для электронных писем и компаний их друзей, кнопку, которая будет добавлять дополнительные формы ввода, и кнопку, которая удаленно отправляет все формы. При отправке форм в каждой форме появляется счетчик до тех пор, пока не будет получен ответ от сервера, после чего, если отправка прошла успешно, форма исчезает, а если произошла ошибка, отображается ошибка.
Я застрял на следующем: чтобы отправить форму удаленно с помощью Redux Form, вам нужно передать ее имя отправляющему компоненту. Я хочу создавать формы программно. Имена будут автоматически увеличивающимися целыми числами, созданными компонентом управления формами и переданными дочерним формам в качестве реквизита. Однако, когда я пытаюсь экспортировать форму, ссылаясь на имя как this.props.name, я получаю сообщение об ошибке: «Uncaught TypeError: Cannot read property 'props' of undefined» — «this» не определено.
Вопросы:
- Верен ли мой подход к решению этой проблемы, или я должен сделать что-то по-другому на базовом уровне?
- Как мне обойти это? Я предполагаю, что это ошибка области видимости?
Мои компоненты:
Компонент управления (создает и удаляет формы, отправляет их и т. д.):
import React, { Component } from 'react';
import { connect } from 'react-redux'
import { submit } from 'redux-form'
import * as actions from '../../actions';
import InviteForm from './inviteForm';
class InvitationFormManager extends Component {
const buildForms = (length) =>{
for (let i = 0; i< length; i++)
{
this.setState({forms:[...this.state.forms, <InviteForm key={i} name={i}>]};
}
}
const addForm = () =>{
this.setState({forms:[...this.state.forms, <InviteForm key={(this.state.forms.length + 1)} name={(this.state.forms.length + 1)}>]});
}
const formSubmit = (form) =>
{
dispatch(submit(form.name))
.then(this.setState({
forms: this.state.forms.filter(f => f.name !== form.name)
}))
}
const submitForms = (){
for(let form of this.state.forms){formSubmit(form)}
}
constructor(props) {
super(props);
this.state = {forms:[]};
}
componentWillMount(){
buildForms(3)
}
render() {
return (<div>
<h5 className="display-6 text-center">Invite your team</h5>
{this.state.forms}
<br />
<button
type="button"
className="btn btn-primary"
onClick={submitForms}
>
Invite
</button>
<button
type="button"
className="btn btn-primary"
onClick={addForm}
>
+
</button>
</div>
);
}
}
export default connect(actions)(InvitationFormManager)
Компонент формы:
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 InviteForm extends Component {
constructor(props) {
super(props);
this.name = this.name.bind(this);
}
handleFormSubmit(props) {
this.props.sendInvitation(props);
}
render() {
if (this.props.submitting) {
return (
<div className="dashboard loading">
<Spinner name="chasing-dots" />
</div>
);
}
const { formName, handleSubmit } = this.props;
return (
<div className="form-container text-center">
<form
className="form-inline"
onSubmit={handleSubmit(this.handleFormSubmit.bind(this))}>
<div className="form-group">
<Field
name="email"
component={renderField}
type="email"
label="Email"
/>
<Field
name="company"
component={renderField}
type="text"
label="Company"
/>
</div>
</form>
<div>
{this.props.errorMessage &&
this.props.errorMessage.invited && (
<div className="error-container">
Oops! {this.props.errorMessage.invited}
</div>
)}
</div>
</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.invite.error,
submitting: state.invite.submitting
};
}
InviteForm = reduxForm({
form: this.props.name,
validate
})(InviteForm);
export default connect(mapStateToProps, actions)(InviteForm);