iT邦幫忙

2022 iThome 鐵人賽

DAY 6
0
Software Development

每天一套件,工作沒煩惱系列 第 6

一天一套件,工作沒煩惱 - formik + yup

  • 分享至 

  • xImage
  •  

今天要介紹 Formik + Yup,會一次介紹兩個套件是因為他們有密不可分的關係

什麼是 Formik,為甚麼需要搭配 Yup?

Formik 是一個表單管理工具,如果不用的話,開發者可能會需要多有 state 去管理,為什麼需要 Yup?是因為 Formik 只做管理但不做驗證,所以我們會需要 Yup 幫我們做驗證

Formik is designed to manage forms with complex validation with ease. Formik supports synchronous and asynchronous form-level and field-level validation. Furthermore, it comes with baked-in support for schema-based form-level validation through Yup. This guide will describe the ins and outs of all of the above.

為什麼需要 Formik+Yup

其實也可以不用,如果你對於你的表單內容有 100% 把握可以掌控的話,就可以不用,不過如果表單內容變多時,狀態會變得很難掌控,透過 Formik+Yup 可以讓我們專注於處理資料,而不用去擔心狀態丟失的問題

環境安裝

Formik:

 npm install formik --save

Yup:

npm i yup

怎麼使用?

接下來會介紹基本的兩個用法,嚴格說起來是一種,因為最終的目的都是要去做表單跟驗證

情境

今天希望有一個 Form 可以去讓顧客輸入 name, age, sex,並且三筆資料都是必填

<Formik>

Github程式碼

is a component that helps you with building forms. It uses a render props pattern made popular by libraries like React Motion and React Router.

<Formik> 就是一個 Component,讓你把資料透過傳遞 Props 的方法傳進去,然後在 Component 中做處理,相信 React 開發者一定都能了解

實作情境題

<Formik
  initialValues={...}
  validationSchema={...}
  onSubmit={(values) => {
    console.log(values);
  }}
>
  ....
</Formik>

initialValues -> 預設值

這個參數接收一個 Object,裡面包有所有表單的預設值,以這題來說,預設值會長這樣:

const initValue = {
  name: "",
  age: "",
  sex: "",
};

validationSchema -> 驗證項目

這是要驗證的部分,我們可以選擇是否為必填,錯誤訊息有是什麼:

const myValidation = Yup.object().shape({
  name: Yup.string().required("名字 為必填欄位"),
  age: Yup.number().required("年齡 為必填欄位"),
  sex: Yup.string().required("性別 為必填欄位"),
});

基本架構就是:

要驗證的項目: Yup
        .型別
        .required(提示訊息)
        .其他條件

onSubmit -> 點擊事件

這是點擊按鈕時所觸發,不過要提醒一下,這邊 button 的 type 要是 submit,不然會沒有效果

表單

{
  ({ errors, touched }) => (
    <Form>
      {/* name */}
      <div>
        <span>name: </span>
        <Field name="name" />
        {errors.name && touched.name ? <div>{errors.name}</div> : null}
      </div>

      {/* age */}
      <div>
        <span>age: </span>
        <Field name="age" />
        {errors.age && touched.age ? <div>{errors.age}</div> : null}
      </div>

      {/* sex */}
      <div>
        <span>sex: </span>
        <Field name="sex" />
        {errors.sex && touched.sex ? <div>{errors.sex}</div> : null}
      </div>

      <button type="submit">Submit</button>
    </Form>
  );
}

今天 Formik 提供了一個 Component 叫<Field>

will automagically hook up inputs to Formik. It uses the name attribute to match up with Formik state. will default to an HTML element.

簡單來說就是打包好的 input

值得注意的是:

{
  errors.name && touched.name ? <div>{errors.name}</div> : null;
}

這行程式碼代表如果有錯誤,會把我們在 validationSchema 所下的相對應錯誤 render 到畫面上,例如:當今天如果我沒有填寫某一必填欄位,就按送出,那麼畫面上可能就會出現XXX 為必填欄位

以上都寫完後,我們來看畫面:

imgur

我們故意不填性別欄位,所以他跟我們提醒說性別 為必填欄位

這邊沒有做美化,所以美化部分就交給讀者了

useFormik

Github程式碼

useFormik() is a custom React hook that will return all Formik state and helpers directly.

基本上他跟我們上面所說的<Formik>一樣,但寫法更漂亮(筆者個人認爲),兩個的比較可以看這篇Issue

實作情境題

基本概念一樣,會有 initialValues 跟 validationSchema

const formik = useFormik({
  initialValues: initValue,
  validationSchema: Yup.object({
    name: Yup.string().required("名字 為必填欄位"),
    age: Yup.number().required("年齡 為必填欄位"),
    sex: Yup.string().required("性別 為必填欄位"),
  }),
  onSubmit: (values) => {
    console.log(values);
  },
});

表單部分:

<form onSubmit={formik.handleSubmit}>
  {/* name */}
  <div>
    <label htmlFor="name">name: </label>
    <input
      type="text"
      name="name"
      id="name"
      onChange={formik.handleChange}
      onBlur={formik.handleBlur}
      value={formik.values.name}
    />
    {formik.touched.name && formik.errors.name && (
      <span className="text-red-400">{formik.errors.name}</span>
    )}
  </div>

  {/* age */}
  <div>
    <label htmlFor="age">age: </label>
    <input
      type="text"
      name="age"
      id="age"
      onChange={formik.handleChange}
      onBlur={formik.handleBlur}
      value={formik.values.age}
    />
    {formik.touched.age && formik.errors.age && (
      <span className="text-red-400">{formik.errors.age}</span>
    )}
  </div>

  {/* sex */}
  <div>
    <label htmlFor="sex">sex: </label>
    <input
      type="text"
      name="sex"
      id="sex"
      onChange={formik.handleChange}
      onBlur={formik.handleBlur}
      value={formik.values.sex}
    />
    {formik.touched.sex && formik.errors.sex && (
      <span className="text-red-400">{formik.errors.sex}</span>
    )}
  </div>

  <button type="submit">Submit</button>
</form>

須在最外層的<form>裡面加上 onSubmit={formik.handleSubmit},這樣 Formik 就會去尋找<form>裡面的 button

結語

其實 Formik 可以玩的東西很多,不過以上的教學已經可以在工作上做使用了,希望各位讀者能夠看得懂,以上就是今天的文章,一樣有問題都歡迎在下方留言~~

那我們明天見~~

我有為了這次的鐵人賽建立了 Github 的專案,有程式碼的問題歡迎去我的Github上面看

參考文章:

https://formik.org/

https://blog.shahednasser.com/how-to-create-and-validate-forms-in-react-using-formik-and-yup/


上一篇
一天一套件,工作沒煩惱 - ES7 React/Redux/GraphQL/React-Native snippets
下一篇
一天一套件,工作沒煩惱 - react-hook-form
系列文
每天一套件,工作沒煩惱30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言