J'utilise le formulaire Formik
avec React. Chaque fois que l'utilisateur soumet (handleSubmit), je mets une option pour annuler ou non la modification ou la conserver.
Dans mon rendu,
<Formik
initialValues={this.state.experiment}
onSubmit={this.handleSubmit}
component={formikProps => (
<ExperimentForm {...formikProps} submitText="Save Changes" />
)}
/>
handleSubmit ()
handleSubmit(formdata: any, actions: any) {
const data = processFormData(formdata);
let changes = this.detectChanges(this.state.experiment, data);
this.setState({ tempFormData: data });
// changed field exists
if (changes.length !== 0) {
this.setState({
isDialogOpen: true,
changedFields: changes,
});
} else {
actions.setSubmitting(false);
this.setState({
message: 'Nothing Changed',
});
}
}
keepChanges () et discardChanges ()
keepChanges () {
const data = this.state.tempFormData
makeMutation(UpdateExperimentQuery, {
update: {
id: this.props.match.params.id,
data,
},
})
.then(responseData => {
console.log(responseData)
this.setState({ isDialogOpen: false });
this.props.history.Push('/i/experiments');
})
.catch(err => {
this.setState({
message: 'Error Updating Experiment',
});
console.log(err);
});
}
discardChanges () {
this.setState({ isDialogOpen: false });
this.componentWillMount();
}
La keepChanges()
met à jour les données avec le champ donné, mais discardChanges
ferme simplement la boîte de dialogue mais ne réinitialise pas les données à leur valeur d'origine même si j'essaie d'appeler componentWillMount()
qui récupère et restitue les données d'origine inchangées dans la base de données.
Comment puis-je réinitialiser les champs lorsque je choisis d'annuler les modifications?
Modifier
discardChanges () {
this.formik.current.resetForm();
this.setState({ isDialogOpen: false });
this.componentWillMount();
}
// J'obtiens une erreur lorsque je fais React.createRef ();
class EditExperiment extends Component<EditExperimentProps, EditState> {
constructor(props: EditExperimentProps) {
super(props);
this.formik = React.createRef();
this.state = {
experiment: null,
message: null,
changedFields: [],
isDialogOpen: false,
tempFormData: []
};
this.handleSubmit = this.handleSubmit.bind(this);
this.clearMessage = this.clearMessage.bind(this);
this.detectChanges = this.detectChanges.bind(this);
this.keepChanges = this.keepChanges.bind(this);
this.discardChanges = this.discardChanges.bind(this);
}
EDIT2
type EditExperimentProps = {
history: RouterHistory,
match: Match,
experiments: ExperimentsState,
refetch: () => void,
};
type EditState = {
experiment: ?Experiment,
message: ?string,
};
class EditExperiment extends Component<EditExperimentProps, EditState> {
constructor(props: EditExperimentProps) {
super(props);
this.formik = React.createRef();
this.state = {
experiment: null,
message: null,
changedFields: [],
isDialogOpen: false,
tempFormData: []
};
this.handleSubmit = this.handleSubmit.bind(this);
this.clearMessage = this.clearMessage.bind(this);
this.detectChanges = this.detectChanges.bind(this);
this.keepChanges = this.keepChanges.bind(this);
this.discardChanges = this.discardChanges.bind(this);
}
Pour réinitialiser le Formik, vous devez appeler resetForm
- voir un exemple ici .
handleSubmit(formdata: any, actions: any) {
...
// changed field exists
if (changes.length !== 0) {
...
} else {
actions.setSubmitting(false);
actions.resetForm();
}
}
ÉDITER:
Il existe une autre façon d'obtenir des "actions" et de les appeler n'importe où dans le composant en utilisant react ref
s:
constructor(props) {
super(props);
this.formik = React.createRef();
}
//somewhere in render
<Formik
ref={this.formik}
initialValues={this.state.experiment}
onSubmit={this.handleSubmit}
component={formikProps => (
<ExperimentForm {...formikProps} submitText="Save Changes" />
)}
/>
// now somewhere else in the same component ...
componentDidUpdate(prevProps) {
if(somethingHappend) {
if(this.formik.current) {
this.formik.current.resetForm();
}
}
}
Vous devez inclure l'état initial lorsque vous souhaitez utiliser resetForm. Exemple:
this.formik.current.resetForm(this.initialState.experiment);
Cela signifie que vous devez également enregistrer l'état initial:
constructor(props) {
super(props);
this.initialState = this.state;
}