Skip to content

Instantly share code, notes, and snippets.

@Fieel
Last active November 19, 2019 09:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Fieel/4b58083547e9cbf6f0472e9100be0090 to your computer and use it in GitHub Desktop.
Save Fieel/4b58083547e9cbf6f0472e9100be0090 to your computer and use it in GitHub Desktop.
Formik delegating submit logic to parent component? Gist created to showcase this specific usecase to a friend
// Core
import React, { Component } from "react";
import { connect } from "react-redux";
// Elementi UI
import ErrorMessage from "../../ui/ErrorMessage";
import LoadingSpinner from "../../ui/LoadingSpinner";
import DistanceTestForm from "./DistanceTestForm";
// Utils
import { isObjectEmpty } from "../../../services/utils";
class ApiTester extends Component {
constructor(props) {
super(props);
this.state = {
error: null,
isLoading: false,
result: {}
};
}
updateDistance = newData => {
this.setState({
isLoading: true
});
fetch(
"https://localhost:5001/api/distance/" +
newData.origin +
"/" +
newData.destination
)
.then(res => res.json())
.then(
data => {
this.setState({
isLoading: false,
result: data,
error: null
});
},
error => {
this.setState({
isLoading: false,
error: error
});
}
);
};
render() {
const { error, isLoading, result } = this.state;
return (
<div className="col-xl-6 col-lg-6 offset-lg-3">
<div className="card shadow mb-4">
<div className="card-header py-3 d-flex flex-row align-items-center justify-content-between">
<h6 className="m-0 font-weight-bold text-primary">
Distance tester
</h6>
</div>
<div className="card-body">
<DistanceTestForm updateDistance={this.updateDistance} />
<br />
{error && <ErrorMessage message={error.toString()} />}
{isLoading && <LoadingSpinner />}
{!isObjectEmpty(result) && JSON.stringify(this.state.result, null, 2)}
</div>
</div>
</div>
);
}
}
// Prendo dallo state globale solo l'access token che mi serve
const mapStateToProps = state => {
return {
accessToken: state.user.accessToken
};
};
export default connect(mapStateToProps)(ApiTester);
// Render Prop
import React from "react";
import { Formik, Form, Field, ErrorMessage } from "formik";
import * as Yup from "yup";
const DistanceTestForm = ({updateDistance}) => (
<Formik
initialValues={{ origin: "", destination: "" }}
validationSchema={validationSchema}
onSubmit={(values, { setSubmitting }) => {
// TODO: chiamata async che fetcha i dati
console.log('submitting',values);
updateDistance(values);
setSubmitting(false);
}}
>
{({ isSubmitting }) => (
<Form>
<div className="form-group">
<label htmlFor="departure">Partenza</label>
<Field type="text" name="origin" className="form-control" />
<ErrorMessage name="origin" component="div" className="text-danger" />
</div>
<div className="form-group">
<label htmlFor="departure">Arrivo</label>
<Field type="text" name="destination" className="form-control" />
<ErrorMessage name="destination" component="div" className="text-danger" />
</div>
<button
type="submit"
disabled={isSubmitting}
className="btn btn-primary"
>
Invia
</button>
</Form>
)}
</Formik>
);
// Schema creato con Yup per creare le validazione del form
const validationSchema = Yup.object().shape({
origin: Yup.string()
.min(6, "Minimo 6 caratteri")
.required("Campo obbligatorio"),
destination: Yup.string()
.min(6, "Minimo 6 caratteri")
.required("Campo obbligatorio")
});
export default DistanceTestForm;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment