iT邦幫忙

2023 iThome 鐵人賽

DAY 22
0
SideProject30

30 天用 Rust 打造 QR Code 製造機系列 第 22

Day 22 - 將表單重構成元件(下)

  • 分享至 

  • xImage
  •  

前情提要:上一篇把 page.tsx 中的表單部分重構整理成一個新的元件,不過搬移的過程中,有一些問題沒有處理好,所以這篇就來處理一下。

如何傳遞 errorspage.tsx

從 React Hook From 中的 errors 因為目前都在 CreateSvgForm.tsx 中,所以要把 errors 傳遞到 page.tsx 中,這樣才能在 page.tsx 中顯示錯誤訊息。

傳遞的方式有很多,因為我們已經使用 Zustand 來管理狀態了,所以可以直接把 errors 存到 Zustand 中,然後在 page.tsx 中取出就可以了。

新增 errorsstore

第一步先把狀態的部分弄好,所以先在 store/index.ts 中新增以下的部分:

import { create } from 'zustand'
import { FieldError } from 'react-hook-form'

type ErrorType = {
  text?: FieldError
  qrType?: FieldError
  qrSize?: FieldError
  qrColor?: FieldError
  qrBgColor?: FieldError
}

interface Store {
  imgSrc: string | null
  setImgSrc: (imgSrc: string | null) => void
  errorsFromForm: ErrorType
  setErrors: (errors: ErrorType) => void
}
const useStore = create<Store>((set) => ({
  imgSrc: null,
  setImgSrc: (imgSrc) => set({ imgSrc }),
  errorsFromForm: {},
  setErrors: (errors) => set({ errorsFromForm: errors })
}))

export default useStore

這裡先定義了 ErrorType 這個型別,然後在 Store 中新增了 errorsFromForm 這個狀態,並且定義了 setErrors 這個方法。

然後為了避免搞混,所以把 errors 改名為 errorsFromForm,這樣就不會跟 React Hook Form 中的 errors 搞混了。

要注意的部分, ErrorType 的型別最好從 react-hook-form 中取得,這樣才不會有錯誤。

CreateSvgForm 元件中取得 errors

接下來就可以在 CreateSvgForm.tsx 中取得 errors 了,只要從 useForm 中取得 setErrors,然後在 useEffect 中把 errors 存到 Zustand 中就可以了:

const { setImgSrc, setErrors } = useStore()

useEffect(() => {
  setErrors(errors)
}, [errors])

最後在 page.tsx 中取得 errorsFromForm 就可以了:

export default function Home() {
  const { imgSrc, errorsFromForm } = useStore()
  const hasErrors = Object.keys(errorsFromForm).length > 0

  return (
    <main className='flex min-h-screen flex-col items-center justify-between p-24'>
      <div className='container mx-auto p-4'>
        <h1 className='text-3xl mb-4'>QR Code 製造器</h1>
        <CreateSvgForm />
        {imgSrc && Object.keys(errorsFromForm).length < 1 ? (
          <div className='flex justify-center mt-10'>
            <Image src={imgSrc} width={500} height={500} alt='QR Code Image' />
          </div>
        ) : (
          <p>
            {hasErrors
              ? '請輸入正確的資訊'
              : '請點擊「產生 QR Code」按鈕'}
          </p>
        )}
      </div>
    </main>
  )
}

可以正常運作就沒問題了👍。

Oct-05-2023 00-23-22

這篇文章用 Zustand 解決了狀態在不同元件間的傳遞問題,是不是感受到了狀態管理的便利性呢?明天來新增 PNG 的表單元件,明天見👋!


上一篇
Day 21 - 將表單重構成元件(上)
下一篇
Day 23 - 運用 Next.js 的 CSS Module 功能修改樣式
系列文
30 天用 Rust 打造 QR Code 製造機30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言