Last active
September 13, 2018 11:43
-
-
Save iBasit/10416c52550bd32e3f4a08b23d5b1ab5 to your computer and use it in GitHub Desktop.
tutorial example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from 'react'; | |
import { Formik, Field, Form } from 'formik'; | |
import {bindActionCreators} from "redux"; | |
import connect from "react-redux/es/connect/connect"; | |
import { contactCompleted, contactHasError, contactLoading, saveContact } from "../actions/contactAction" | |
import * as Yup from 'yup'; | |
/** | |
* TODO Contact us form | |
* √ - first name, last name and email request | |
* √ - add validation | |
* √ - show loading text on submit and disable button | |
* √ - send data to server | |
* √ - show thank you message or error message on failure | |
*/ | |
// While you can use any validation library (or write you own), Formik | |
// comes with special support for Yup by @jquense. It has a builder API like | |
// React PropTypes / Hapi.js's Joi. You can define these inline or, you may want | |
// to keep them separate so you can reuse schemas (e.g. address) across your application. | |
const SignUpSchema = Yup.object().shape({ | |
email: Yup.string() | |
.email('Invalid email address') | |
.required('Required'), | |
firstName: Yup.string() | |
.min(2, 'Must be longer than 2 characters') | |
.max(20, 'Nice try, nobody has a first name that long') | |
.required('Required'), | |
lastName: Yup.string() | |
.min(2, 'Must be longer than 2 characters') | |
.max(20, 'Nice try, nobody has a last name that long') | |
.required('Required'), | |
}); | |
const Contact = ({saveContact, contactCompleted, contactHasError, contactLoading, isLoading, isSuccess, isError, errorMsg}) => ( | |
<div> | |
<h1>Contact us</h1> | |
<Formik | |
initialValues={{ | |
firstName: '', | |
lastName: '', | |
email: '', | |
phone: '' | |
}} | |
validationSchema={SignUpSchema} | |
onSubmit={values => { | |
contactLoading(true); | |
saveContact(values); | |
}} | |
render={({ errors, touched }) => ( | |
<div> | |
{isSuccess ? <div className="text-success">Thank you for submitting the form</div> : ''} | |
{isError ? <div className="text-danger">{errorMsg}</div> : ''} | |
<Form className={isSuccess ? 'hidden' : ''}> | |
<div className="form-row col-4"> | |
<label htmlFor="firstName">First Name</label> | |
<Field name="firstName" placeholder="Jane" className={errors.firstName && touched.firstName ? "form-control is-invalid" : !errors.firstName && touched.firstName ? "form-control is-valid": "form-control"} /> | |
<div className="valid-feedback"> | |
Looks good! | |
</div> | |
<div className="invalid-feedback"> | |
{errors.firstName} | |
</div> | |
</div> | |
<br/> | |
<label htmlFor="lastName">Last Name</label> | |
<Field name="lastName" placeholder="Doe" /> | |
{errors.lastName && touched.lastName && ( | |
<div className="field-error text-danger">{errors.lastName}</div> | |
)} | |
<br/> | |
<label htmlFor="email">Email</label> | |
<Field name="email" placeholder="[email protected]" type="email" /> | |
{errors.email && touched.email && ( | |
<div className="field-error text-danger">{errors.email}</div> | |
)} | |
<br/> | |
<label>Phone</label> | |
<Field name="phone" placeholder="ex: 00448382922" /> | |
<br/><br/> | |
<button type="submit" disabled={isLoading}>Submit</button> | |
{isLoading ? 'loading...' : ''} | |
</Form> | |
</div> | |
)} | |
/> | |
</div> | |
); | |
const mapStateToprops = (state,props) => ({ | |
...state.contact, | |
...props | |
}); | |
const mapDispatchToProps = dispatch => bindActionCreators({ | |
saveContact, contactCompleted, contactHasError, contactLoading | |
},dispatch); | |
export default connect( | |
mapStateToprops, | |
mapDispatchToProps | |
)(Contact); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import {CONTACT_COMPLETED, CONTACT_ERROR, CONTACT_LOADING} from "../reducers/contactReducer"; | |
export const contactCompleted = () => ({ | |
type: CONTACT_COMPLETED, | |
isSuccess: true | |
}); | |
export const contactLoading = (boolean) => ({ | |
type: CONTACT_LOADING, | |
isLoading: boolean | |
}); | |
export const contactHasError = (boolean, errorMsg) => ({ | |
type: CONTACT_ERROR, | |
isError: boolean, | |
errorMsg | |
}); | |
export const saveContact = (values) => { | |
return dispatch => fetch('http://httpbin.org/delay/5', { | |
method: 'POST', | |
headers: { | |
'Accept': 'application/json', | |
'Content-Type': 'application/json' | |
}, | |
body: values | |
}) | |
.then((response) => { | |
dispatch(contactLoading(false)); | |
dispatch(contactCompleted(true)); | |
dispatch(contactHasError(false, '')); | |
console.log('response before', response); | |
return response.json(); | |
}) | |
.then((response) => { | |
console.log('resonse after ', response); | |
}) | |
.catch((promise) => { | |
dispatch(contactLoading(false)); | |
dispatch(contactHasError(true, promise.toLocaleString())); | |
console.log('error:', promise.toLocaleString()); | |
}); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export const CONTACT_LOADING = 'CONTACT_LOADING'; | |
export const CONTACT_COMPLETED = 'CONTACT_COMPLETED'; | |
export const CONTACT_ERROR = 'CONTACT_ERROR'; | |
let initialState = { | |
isLoading: false, | |
isSuccess: false, | |
isError: false, | |
errorMsg: '' | |
}; | |
export default function contact(state =initialState,action ){ | |
switch (action.type){ | |
case CONTACT_COMPLETED: | |
return { | |
...state, | |
isSuccess: action.isSuccess | |
}; | |
case CONTACT_LOADING: | |
return { | |
...state, | |
isLoading: action.isLoading | |
}; | |
case CONTACT_ERROR: | |
return { | |
...state, | |
isError: action.isError, | |
errorMsg: action.errorMsg | |
}; | |
default: | |
return state; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment