So habe ich ein einfaches Formular Assistenten aus einem Beispiel in Redux-Form genommen. Ich möchte Felder mit Daten initialisieren, die von einem asynchronen API-Aufruf empfangen werden.Initialisierung Redux-Formular-Assistent
Die Art, wie es jetzt ist, Felder werden nicht ohne den Parameter enableReinitialize: true
auf jeder Seite des Assistenten ausgefüllt, da die Initialisierung bereits einmal beim Starten der Serveranforderung erfolgt. Wenn ich andererseits enableReinitialize: true
zu den Assistentenseiten hinzufüge, werden alle Benutzereingaben beim Verschieben von Seite zu Seite verworfen, und initialValues wird wieder gesetzt.
Ich habe auch versucht, die keepDirtyOnReinitialize: true
Option in Verbindung mit enableReinitialize: true
zu jeder Seite hinzuzufügen, aber ohne Erfolg.
Was wäre die korrekte Methode zum Erstellen eines Formularassistenten, wenn eine Untergruppe von Feldern durch asynchron abgerufene Daten initialisiert werden muss, die vom Benutzer überschrieben werden müssen?
WizardForm.jsx:
import React, {Component, PropTypes} from 'react'
import WizardFormFirstPage from './WizardFormFirstPage.jsx'
import WizardFormSecondPage from './WizardFormSecondPage.jsx'
import WizardFormThirdPage from './WizardFormThirdPage.jsx'
import fetchData from "./fetchData.jsx";
import {connect} from "react-redux";
class WizardForm extends Component {
constructor(props) {
super(props);
this.nextPage = this.nextPage.bind(this);
this.previousPage = this.previousPage.bind(this);
this.state = {
page: 1
}
}
componentWillMount() {
if (!this.props.hasFetched)
this.props.fetchData();
}
nextPage() {
this.setState({ page: this.state.page + 1 })
}
previousPage() {
this.setState({ page: this.state.page - 1 })
}
render() {
const { onSubmit } = this.props;
const { page } = this.state;
return (
<div>
{page === 1 && <WizardFormFirstPage onSubmit={this.nextPage} initialValues={this.props.initialValues}/>}
{page === 2 &&
<WizardFormSecondPage previousPage={this.previousPage} initialValues={this.props.initialValues}
onSubmit={this.nextPage}/>}
{page === 3 &&
<WizardFormThirdPage previousPage={this.previousPage} initialValues={this.props.initialValues}
onSubmit={onSubmit}/>}
<label>{this.props.isFetching ? "Fetching data.." : "Fetched data successfully." }</label>
</div>
)
}
}
function mapStateToProps(state) {
return {
initialValues: state.prefill.data,
isFetching: state.prefill.fetching,
hasFetched: state.prefill.fetched
}
}
WizardForm = connect(
mapStateToProps,
{fetchData}
)(WizardForm);
WizardForm.propTypes = {
onSubmit: PropTypes.func.isRequired,
initialValues: PropTypes.object
};
export default WizardForm;
WizardFormFirstPage.jsx:
class WizardFormFirstPage extends Component {
constructor(props) {
super(props);
}
render() {
const {handleSubmit} = this.props;
return (
<form onSubmit={handleSubmit}>
<Field name="firstName" type="text" component={renderField} label="First Name"/>
<Field name="lastName" type="text" component={renderField} label="Last Name"/>
<Field name="downPayment" type="text" component={renderField}
label="Down Payment" normalize={normalizeDownPayment}/>
<div>
<button type="submit" className="next">Next</button>
</div>
</form>
)
};
}
WizardFormFirstPage = reduxForm({
form: "wizard",
destroyOnUnmount: false,
forceUnregisterOnUnmount: true,
//enableReinitialize: true, // <-- !
validate
})(WizardFormFirstPage);
export default WizardFormFirstPage;
fetchData.jsx:
export default function fetchData() {
return (dispatch) => {
dispatch({type: "FETCH_DATA_START"});
axios.get("http://rest.learncode.academy/api/nordischby/customer")
.then(response => {
dispatch({type: "FETCH_DATA_FINISH", data: response.data[0]});
})
.catch(error => {
console.error(error);
});
}
};
prefill.jsx:
const initialState = {
data: {},
fetching: false,
fetched: false,
error: null
};
const prefillReducer = (state = initialState, action) => {
switch (action.type) {
case "FETCH_DATA_START":
return {
...state,
fetching: true
};
case "FETCH_DATA_FINISH":
return {
...state,
data: action.data,
fetching: false,
fetched: true
};
default:
return state
}
};
export default prefillReducer;