iT邦幫忙

0

React Custom hook 踩坑日記 - form hook

  • 分享至 

  • xImage
  •  

今天分享一個簡單又常用到的方法來處理表單,先舉個新手進入React處理表單時常用到的例子:

// 使用useState來記錄表單欄位訊息
const [nativeForm, setNativeForm] = useState({
  user: '',
  pwd: ''
})
// 定義onChange function
const nativeFormChange = e => setNativeForm({...nativeForm, [e.target.name]: e.target.value })
<!-- in return -->
<fieldset>
  <legend>一般的useState</legend>
  <div>
    <label htmlFor="user">用戶名</label>
    <input 
      id="user"
      name="user"
      value={nativeForm.user}
      onChange={nativeFormChange}
    />
  </div>
  <div>
    <label htmlFor="pwd">密碼</label>
    <input 
      id="pwd"
      name="pwd"
      type="password"
      value={nativeForm.pwd}
      onChange={nativeFormChange}
    />
  </div>
</fieldset>

按照上次講的邏輯來做簡化,所以一步一步來,現創一個新的.js,檔案來整理這邊的useState和onChange function:

// useForm.js
import { useState } from "react"

const useForm = (defaultValues) => {
  // 先另立一個form state 的 object
  const [state, setState] = useState(defaultValues || {});
  // 基礎的塞入方法,當input form 的 name 有對應到的時候就可改變該狀態
  const handleChange = e => {
    setState(state => ({ ...state, [e.target.name]: e.target.value }));
  }
  // 回傳form state && handleChange function
  return [state, handleChange];
}

export default useForm;

接著,回到原本的component裡面做修改:

// 改為引入剛剛做好的useForm
const [nativeForm, nativeFormChange] = useForm({
  user: '',
  pwd: ''
})

稍微修改一下新的function命名

<!-- in return -->
<fieldset>
  <legend>custom hook useForm</legend>
  <div>
    <label htmlFor="user">用戶名</label>
    <input 
      id="user"
      name="user"
      value={nativeForm.user}
      onChange={nativeFormChange}
    />
  </div>
  <div>
    <label htmlFor="pwd">密碼</label>
    <input 
      id="pwd"
      name="pwd"
      type="password"
      value={nativeForm.pwd}
      onChange={nativeFormChange}
    />
  </div>
</fieldset>

以上就是一個簡單的應用分享,開發沒有絕對的事情,但多了解不同的作法與認知不同做法之間的優缺點,才是真正重要的事情,拿著自己的主觀意見綁架他人的想法時,格局小了,眼界也小了,哪還來的了進步的空間。希望我的作法能夠幫助到大家,之後也會分享更多我已知的作法。


圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言