ทำ Multi-Step Forms ด้วย React Hook Form และ useContext

Jidapa Pattanang
THE EXISTING COMPANY
4 min readNov 27, 2019

ก่อนหน้านี้ได้มีโอกาสลองทำ Multi-Step Forms เป็นครั้งแรกเลยอยากมาลองแชร์วิธีการทำให้ให้เพื่อน ๆ ได้ดู จากบทความก่อนหน้าที่ได้ลองแชร์วิธีการทำ Form Validation ด้วย Formik และ Yup ไป (หากใครยังไม่ได้อ่านสามารถอ่านได้ที่ คลิก) วันนี้จึงอยากจะมาเสนอวิธีการทำ Multi-Step Forms ด้วยการใช้ react hooks, react hook form, yup, และ useContext

แนะนำสิ่งที่จะใช้

  • React Hooks คือ ฟีเจอร์ของ react ที่ช่วยเข้ามาจัดการกับ state และ lifecycle ของ function components
  • React Hook Form คือ library ที่ช่วยในการจัดการฟอร์ม ซึ่งเจ้าตัวนี้เป็นตัวที่ขึ้นชื่อในเรื่องของ Performance, ลดการ code ที่ใช้การจัดการกับฟอร์ม, ลดจำนวนการ render ซ้ำ ๆ และ mount ได้เร็วขึ้น
  • Yup คือ Schema ของข้อมูลที่อยู่ในรูป Object ซึ่งใช้สำหรับการทำ validation
  • useContext คือ Hook API ที่ช่วยในการจัดการกับ global state คล้าย ๆ กับ redux

โจทย์สำหรับการทำ Form

  1. อยากทำ Form เป็น Step ๆ
  2. อยาก validation Form ถ้ากด Next ต้อง validate ทันที
  3. ถ้าข้อมูลถูกต้องถึงกด Next ได้
  4. ถ้ากด Back ข้อมูลที่กรอกไว้ก่อนหน้าต้องยังอยู่ และสามารถแก้ไขได้
  5. ถ้ากรอกข้อมูลสำเร็จทุก Step อยากได้ข้อความบอกว่าลงทะเบียนสำเร็จแล้วนะ พร้อมกับปุ่มกลับไปหน้าแรก Form ต้อง reset ทั้งหมด

UI คร่าว ๆ

มาลงมือทำกันเถอะ

  1. ติดตั้ง Material UI สำหรับใช้ CSS
npm install @material-ui/core

2. สร้าง Form สำหรับทำการสมัครสมาชิก

โดยเราจะแบ่งออกเป็น 4 components ได้แก่

  • Register เป็น components หลักที่เป็นเหมือน layout ของ register
  • StepperForm ใช้ในการทำ Stepper และเป็น parent components ของ sub form
  • Infomation เป็น Form สำหรับข้อมูลส่วนตัวทั่ว ๆ ไป
  • Account เป็น Form สำหรับในส่วนของบัญชีผู้ใช้

StepperForm.js

ผลลัพธ์

Information.js

Account.js

3. เมื่อเตรียม Form ครบทั้งสองหน้า ให้กลับไปแก้ Code ที่ StepperForm.js โดยเพิ่ม Information และ Account components เข้ามา หลังจากนั้นให้แก้ไข Switch Case ให้ return Components แทน

StepperForm.js

4. ติดตั้ง React Hook Form สำหรับจัดการ Form

npm install react-hook-form

5. แก้ไขไฟล์ Stepper.js ดังนี้

  • import react-hook-form
  • ใส่ tag form ครอบ Stepper
  • onSubmit มีการตรวจสอบเงื่อนไข ถ้า index เป็น 0 ให้ submit information form ถ้า index เป็น 1 ให้ submit account form

6. ติดตั้ง Yup เพื่อทำ validate

npm install yup
  • สร้าง Schema สำหรับ inforamtion
  • สร้าง Schema สำหรับ Accounting

7. กลับไปที่ไฟล์ Stepper.js เพื่อทำสิ่งต่อไปนี้

  • import yup เพื่อใช้ yup
  • เพิ่ม informationSchema และ accountSchema เข้าไปในไฟล์นี้
  • Set validationSchemaให้กับ useForm

8. แก้ไขการ return ของ function getStepContent ให้ส่ง props ที่เป็น useForm ไปให้ component ลูกด้วย เพื่อที่จะใช้งาน yup validate และ react hook formได้

9. แก้ไข information.js ดังนี้

  • destructure formProps แบบด้านล่าง 👇🏻
formProps: { register, errors }
  • เพิ่ม inpuRef โดยมีค่าเป็น register ให้กับแต่ละ TextField เพื่อเป็นการลงทะเบียนให้ react hook form รู้จักกับ แต่ละ input
  • เพิ่ม name ให้กับแต่ละ TextField และ name ต้อง unique
  • จัดการ errors ของแต่ละ field

10. แก้ไข Account.js เช่นเดียวกับ information.js

11. เมื่อถึงตรงนี้แล้วแล้วทุกคนลองกด Next จะยังไม่ validate เนื่องจากว่า Button กำลังเรียกใช้งาน function handleNext() เมื่อมีการ click ไม่ต้องกังวลไป คุณแค่ต้องกลับไปแก้ไขไฟล์ StepperForm.js อีกครั้ง ดังนี้

  • Button ด้านล่างให้ใส่ type เป็น submit
  • ให้ onSubmit เรียก handleNext()

ผลลัพธ์ที่ได้คือเมื่อกด Next ตัว validate จะทำงาน ดังนี้

12. ทำให้ Form ของเราจำข้อมูลของ Information Form และ Account Form ด้วย useContext

  • สร้าง File สำหรับ create store (src/Context/store.js)

13. ไปที่ Top Level ของ Component ที่เราจะใช้ (ในทีนี้จะไปที่ index.js)

  • import file src/Context/store ซึ่งเป็น Store Context ที่เราสร้างไว้เข้ามา

14. กลับไปที่ StepperForm.js

  • import Store เพื่อเรียกใช้งาน global state
  • ตอน onSubmit ให้ทำการ set state ให้กับ store

15. ทำให้แต่ละ Field มีค่า defaultValue เท่ากับ global state ดังนี้

  • เรียกใช้ store context ที่ StepperForm.js
  • ส่ง data จาก StepperForm ไปให้ Information และ Account Component
  • set defaultValue ให้กับแต่ละ TextFiled

StepperForm.js

Information.js

Account.js

ผลลัพธ์

สามารถดู Code เพิ่มเติมได้ที่

สรุป

นี่เป็นเพียงการเริ่มต้นในการทำ Stepper ของเจ้าของกระทู้ที่อยากลองของใหม่ซึ่งก็คือ React Hook Form ที่ทุกคนล้วนแนะนำมาว่าช่วยเรื่อง Performance เป็นอย่างมาก อยากให้ทุกคนไปลองเล่นดู เพราะมันอ่านง่ายมาก แถม document ของ react-hook-form ก็เขียนละเอียดมากแล้ว

--

--