Я создаю простое приложение (контактную форму) с Rekit Studio и использую Redux-Saga для подключения формы к базе данных Firebase (Firestore).
Я искал примеры и даже читал всю документацию Rekit,Rekit - это здорово, но я не нашел примеров или документации для решения этой проблемы.
Я использую этот код для построения страницы:
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import * as actions from './redux/actions';
import { AvField, AvForm } from 'availity-reactstrap-validation';
import memobind from 'memobind';
export class Form01 extends Component {
static propTypes = {
form01: PropTypes.object.isRequired,
actions: PropTypes.object.isRequired,
};
state = {
name: '',
email: '',
formError: false
};
validateForm() {
const hasError = !this.state.name.trim() || !this.state.email.trim();
this.setState({
formError: hasError,
});
return !hasError;
}
handleNameChange(evt) {
this.setState({
name: evt.target.value,
});
}
handleEmailChange(evt) {
this.setState({
email: evt.target.value,
});
}
handleSubmit(evt) {
// evt.preventDefault();
evt.persist();
if (!this.validateForm()) {
return;
}
this.props.actions
.saveForm01({
name: this.state.name,
email: this.state.email
})
.then(() => {
this.props.history.push('/form-01');
});
}
render() {
const { saveForm01Error, saveForm01Pending } = this.props.form01;
const { formError, name, email } = this.state;
const nameError = formError && !name.trim();
const emailError = formError && !email.trim();
return (
<div className="form-01-form-01">
<AvForm onSubmit={memobind(this, 'handleSubmit')}>
<fieldset disabled={saveForm01Pending}>
<AvField
name="name"
type="text"
placeholder="Nome completo"
value={this.state.name}
onChange={memobind(this, 'handleNameChange')}
required
/>
{nameError && <div className="error-tip">Name is required.</div>}
<AvField
name="email"
type="email"
placeholder="E-mail"
value={this.state.email}
onChange={memobind(this, 'handleEmailChange')}
required
/>
{emailError && <div className="error-tip">E-mail is required.</div>}
</fieldset>
<button type="submit" disabled={saveForm01Pending}>
{saveForm01Pending ? 'Enviando...' : 'Enviar'}
</button>
{saveForm01Error && <div className="error-tip">Save form01 failed: {saveForm01Error}</div>}
</AvForm>
</div>
);
}
}
/* istanbul ignore next */
function mapStateToProps(state) {
return {
form01: state.form01,
};
}
/* istanbul ignore next */
function mapDispatchToProps(dispatch) {
return {
actions: bindActionCreators({ ...actions }, dispatch),
};
}
export default connect(
mapStateToProps,
mapDispatchToProps,
)(Form01);
Страница отображается без ошибок, нопроблема в том, когда я подключаюсь к Redux / Saga:
import { all, put, select, takeLatest } from 'redux-saga/effects';
import {
FORM_01_SAVE_FORM_01_BEGIN,
FORM_01_SAVE_FORM_01_SUCCESS,
FORM_01_SAVE_FORM_01_FAILURE,
FORM_01_SAVE_FORM_01_DISMISS_ERROR,
} from './constants';
import rsf from '../../../rsf';
export function saveForm01(data) {
// If need to pass args to saga, pass it with the begin action.
// return {
// type: FORM_01_SAVE_FORM_01_BEGIN,
// };
return (dispatch) => {
dispatch({
type: FORM_01_SAVE_FORM_01_BEGIN,
});
const promise = new Promise((resolve, reject) => {
const Form01 = {};
const form01 = new Form01();
form01.save(data).then(() => {
dispatch({
type: FORM_01_SAVE_FORM_01_SUCCESS,
data: {},
});
resolve();
}, (err) => {
dispatch({
type: FORM_01_SAVE_FORM_01_FAILURE,
data: {
error: err,
},
});
reject();
});
});
return promise;
};
}
export function dismissSaveForm01Error() {
return {
type: FORM_01_SAVE_FORM_01_DISMISS_ERROR,
};
}
// worker Saga: will be fired on FORM_01_SAVE_FORM_01_BEGIN actions
export function* doSaveForm01() {
// If necessary, use argument to receive the begin action with parameters.
let res;
try {
// Do Ajax call or other async request here. delay(20) is just a placeholder.
const newForm01a = yield select(state => state.listForm01.name);
const newForm01b = yield select(state => state.listForm01.email);
res = yield all(
rsf.firestore.addDocument,
'Form01',
{
nome: newForm01a,
email: newForm01b
},
);
} catch (err) {
yield put({
type: FORM_01_SAVE_FORM_01_FAILURE,
data: { error: err },
});
return;
}
// Dispatch success action out of try/catch so that render errors are not catched.
yield put({
type: FORM_01_SAVE_FORM_01_SUCCESS,
data: res,
});
}
/*
Alternatively you may use takeEvery.
takeLatest does not allow concurrent requests. If an action gets
dispatched while another is already pending, that pending one is cancelled
and only the latest one will be run.
*/
export function* watchSaveForm01() {
yield takeLatest(FORM_01_SAVE_FORM_01_BEGIN, doSaveForm01);
}
// Redux reducer
export function reducer(state, action) {
switch (action.type) {
case FORM_01_SAVE_FORM_01_BEGIN:
return {
...state,
saveForm01Pending: true,
saveForm01Error: null,
};
case FORM_01_SAVE_FORM_01_SUCCESS:
return {
...state,
saveForm01Pending: false,
saveForm01Error: null,
};
case FORM_01_SAVE_FORM_01_FAILURE:
return {
...state,
saveForm01Pending: false,
saveForm01Error: action.data.error,
};
case FORM_01_SAVE_FORM_01_DISMISS_ERROR:
return {
...state,
saveForm01Error: null,
};
default:
return state;
}
}
Кто-нибудь, пожалуйста, можете дать мне свет?