- This is a simple note about Taming Forms in React - JARED PALMER on youtube, which is an introduction about formik.
- the first step original code is adapted from React Offical Website
Last active
June 4, 2019 02:08
-
-
Save pjchender/563c83e7281edfc09445e3d2e897d402 to your computer and use it in GitHub Desktop.
Reat Formik
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
/* demo use for array of objects with formik */ | |
import React from 'react'; | |
import { Formik, Field, Form, FieldArray, ErrorMessage } from 'formik'; | |
import Debug from './Debug'; | |
// import * as Yup from 'yup'; | |
// STEP 1: 定義 initialValues | |
const initialValues = { | |
friends: [ | |
{ | |
name: '', | |
email: '', | |
}, | |
], | |
}; | |
const Invitation = () => ( | |
<div> | |
<h1>Invite Friends</h1> | |
{/* STEP 2: | |
將 Formik 把 Form 包起來 | |
並帶入 `initialValues` 和 `onSubmit(<values>)*/} | |
<Formik | |
initialValues={initialValues} | |
onSubmit={(values) => { | |
setTimeout(() => { | |
alert(JSON.stringify(values, null, 2)); | |
}, 500); | |
}} | |
> | |
{/* STEP 3: 把 form 用一個 function({values, isSubmitting}) 包起來*/} | |
{({ values, isSubmitting }) => ( | |
<div> | |
<div className="row"> | |
{/* STEP 6: 如果資料是 array of objects 可以使用 <FieldArray> */} | |
<Form className="col s-12"> | |
<FieldArray name="friends"> | |
{/* STEP 7: 在 FieldArray 中可以拿到 push 和 remove 的方法 */} | |
{({ push, remove }) => ( | |
<> | |
{values.friends && | |
values.friends.length > 0 && | |
values.friends.map((value, index) => ( | |
<div className="row"> | |
<div className="col"> | |
{/* STEP 4: 把 name 的名稱和 values 內的資料對應 */} | |
<Field name={`friends[${index}].name`} type="text"> | |
{/* STEP 5-1: 有需要可以把屬性拿出來自己組 input */} | |
{({ field, form }) => ( | |
<input | |
{...field} | |
type="text" | |
placeholder="Jane Doe" | |
/> | |
)} | |
</Field> | |
</div> | |
<div className="col"> | |
{/* STEP 5-2: 或者直接用 Field 帶入需要的屬性 */} | |
<Field | |
name={`friends[${index}].email`} | |
type="email" | |
placeholder="jane@example.com" | |
/> | |
</div> | |
<div className="col"> | |
<button type="button" onClick={() => remove(index)}> | |
X | |
</button> | |
</div> | |
</div> | |
))} | |
<button | |
type="button" | |
className="waves-effect waves-light btn-small" | |
onClick={() => push({ name: '', email: '' })} | |
> | |
Add Friend | |
</button> | |
</> | |
)} | |
</FieldArray> | |
<button | |
type="submit" | |
className="waves-effect waves-light btn-small w-100" | |
disabled={isSubmitting} | |
> | |
Submit | |
</button> | |
</Form> | |
</div> | |
<div className="col s-12"> | |
<Debug /> | |
</div> | |
</div> | |
)} | |
</Formik> | |
</div> | |
); | |
export default Invitation; |
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
// STEP7: create onSubmit function as props passed into <Formik /> as a callback function after handleSubmit | |
import React from 'react'; | |
class MiniFormik extends React.Component { | |
state = { | |
values: this.props.initialValues || {}, | |
touched: {}, | |
errors: {}, | |
}; | |
handleChange = (event) => { | |
const target = event.target; | |
const value = target.type === 'checkbox' ? target.checked : target.value; | |
const name = target.name; | |
this.setState((prevState) => ({ | |
values: { | |
...prevState.values, | |
[name]: value, | |
}, | |
})); | |
}; | |
handleBlur = (event) => { | |
const target = event.target; | |
const name = target.name; | |
this.setState((prevState) => ({ | |
touched: { | |
...prevState.touched, | |
[name]: true, | |
}, | |
})); | |
}; | |
handleSubmit = (event) => { | |
const { onSubmit } = this.props; | |
const { values } = this.state; | |
event.preventDefault(); | |
onSubmit(values); | |
}; | |
render() { | |
const { children } = this.props; | |
return children({ | |
...this.state, | |
handleChange: this.handleChange, | |
handleBlur: this.handleBlur, | |
handleSubmit: this.handleSubmit, | |
}); | |
} | |
} | |
class Reservation extends React.Component { | |
render() { | |
return ( | |
<MiniFormik | |
initialValues={{ | |
isGoing: true, | |
numberOfGuests: 2, | |
}} | |
onSubmit={(values) => alert(JSON.stringify(values), null, 2)} | |
> | |
{({ | |
values, | |
touched, | |
errors, | |
handleChange, | |
handleBlur, | |
handleSubmit, | |
}) => ( | |
<form onSubmit={handleSubmit}> | |
<label> | |
Is going: | |
<input | |
name="isGoing" | |
type="checkbox" | |
checked={values.isGoing} | |
onChange={handleChange} | |
onBlur={handleBlur} | |
/> | |
</label> | |
<br /> | |
<label> | |
Number of guests: | |
<input | |
name="numberOfGuests" | |
type="number" | |
value={values.numberOfGuests} | |
onChange={handleChange} | |
onBlur={handleBlur} | |
/> | |
</label> | |
<pre> | |
{JSON.stringify( | |
{ | |
values, | |
touched, | |
errors, | |
}, | |
null, | |
2 | |
)} | |
</pre> | |
</form> | |
)} | |
</MiniFormik> | |
); | |
} | |
} | |
export default Reservation; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment