我正在嘗試建立一個多步驟表單,我將資料放在一個單獨的檔案中,用於這樣的常數
從「react」匯入{lazy};
export const steps = [ { id: 0, name: 'Personal Info', component: lazy(() => import('../components/PersonalInfo')), }, ];
我將它傳遞給上下文中的自訂掛鉤
const dataSteps = useMultiStep(steps); const { next, back, currentStep, isFirst } = dataSteps;
這是自訂掛鉤
import { useState } from 'react'; import { MultistepProps } from '../@types/Multiform'; const useMultiStep = (steps: MultistepProps[]) => { const [step, setStep] = useState(0); const isLast = step === steps?.length - 1; const isFirst = step === 0; const next = (): void => { if (isLast) return; setStep((current) => current + 1); }; const back = (): void => { if (isFirst) return; setStep((current) => current - 1); }; return { step, next, back, currentStep: steps[step], isFirst, }; }; export default useMultiStep;
我在這裡使用動態元件
import FormInterface from './interface/FormInterface'; import useApp from './hooks/useApp'; import { Suspense } from 'react'; function App() { const data = useApp(); const { currentStep, next, back, isFirst } = data; const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); next(); }; return ( <FormInterface> <form onSubmit={handleSubmit} className="flex flex-col h-full py-5 group" noValidate={true} > {currentStep.component && ( <> <h1 className="text-3xl font-bold text-marineBlue"> {currentStep?.name} </h1> <Suspense fallback={<div>Loading...</div>}> <currentStep.component /> //here </Suspense> <div className={`mt-4 sm:mt-auto flex ${ isFirst ? 'justify-end' : 'justify-between' }`} > <button type="button" className={`hover:text-marineBlue font-bold text-coolGray py-2 px-5 rounded-md text-[13px] ${ isFirst ? 'hidden' : 'block' }`} onClick={back} > Go Back </button> <button type="submit" className="hover:bg-purplishBlue bg-marineBlue text-white py-2 px-5 rounded-md text-[12px] group-invalid:pointer-events-none group-invalid:opacity-30 self-end" > Next Step </button> </div> </> )} </form> </FormInterface> ); } export default App;
我的vite設定是這樣的
import { defineConfig } from 'vite'; import react from '@vitejs/plugin-react'; // https://vitejs.dev/config/ export default defineConfig({ plugins: [react()], });
嘗試了所有方法後,我仍然遇到此錯誤,不是第一次渲染,而是在元件重新載入時出現
App.tsx:7 未捕獲類型錯誤:無法解構“data”的屬性“currentStep”,因為它為空。 在應用程式 (App.tsx:7:11) 在 renderWithHooks (react-dom.development.js:16305:18) 在 mountInminatedComponent (react-dom.development.js:20074:13) 在開始工作(react-dom.development.js:21587:16) 在 HTMLUnknownElement.callCallback2 (react-dom.development.js:4164:14) 在 Object.invokeGuardedCallbackDev (react-dom.development.js:4213:16) 在 invokeGuardedCallback (react-dom.development.js:4277:31) 在 beginWork$1 (react-dom.development.js:27451:7) 在 PerformUnitOfWork (react-dom.development.js:26557:12) 在工作LoopSync (react-dom.development.js:26466:5)
我相信這是一個人力資源管理問題,因為它就像加載整個頁面,僅包含組件,因為狀態丟失,並且useMultisteps
上的信息丟失,但我只是找不到一種方法來實現它工作,請幫助我,教我更好的方法來完成我想做的事情
P粉5485126372023-11-11 11:35:58
當您更新元件時,您的狀態似乎丟失了(可能是因為 useApp() 掛鉤在資料準備好之前傳回 null
)。
例如將 useApp 掛鉤包裝在 useMemo 掛鉤中,以確保它只被呼叫一次:
const data = useMemo(() => useApp(), []);
總而言之,這將確保 useApp 掛鉤僅被調用一次,並且它的返回值會被記憶,即使組件由於 HMR 而重新渲染也是如此。
第二個建議:嘗試修改您的程式碼,如下所示:
const { currentStep, next, back, isFirst } = 資料 ?? {};
這將確保解構操作僅在資料物件不為空時發生。