Saya cuba mencipta borang berbilang langkah dan saya meletakkan data dalam fail berasingan untuk pemalar seperti ini
import {lazy} daripada "react"
export const steps = [ { id: 0, name: 'Personal Info', component: lazy(() => import('../components/PersonalInfo')), }, ];
Saya menghantarnya ke cangkuk tersuai dalam konteks
const dataSteps = useMultiStep(steps); const { next, back, currentStep, isFirst } = dataSteps;
Ini adalah cangkuk tersuai
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;
Saya menggunakan komponen dinamik di sini
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;
Konfigurasi vite saya adalah seperti ini
import { defineConfig } from 'vite'; import react from '@vitejs/plugin-react'; // https://vitejs.dev/config/ export default defineConfig({ plugins: [react()], });
Selepas mencuba segala-galanya, saya masih mendapat ralat ini, bukan pada paparan pertama, tetapi apabila komponen dimuat semula
App.tsx:7 Uncaught TypeError: Tidak boleh memusnahkan 'currentStep' harta 'data' kerana ia adalah batal. Dalam aplikasi (App.tsx:7:11) dalam renderWithHooks (react-dom.development.js:16305:18) dalam mountInminatedComponent (react-dom.development.js:20074:13) Semasa mula bekerja (react-dom.development.js:21587:16) di HTMLUnknownElement.callCallback2 (react-dom.development.js:4164:14) di Object.invokeGuardedCallbackDev (react-dom.development.js:4213:16) dalam invokeGuardedCallback (react-dom.development.js:4277:31) di beginWork$1 (react-dom.development.js:27451:7) dalam PerformUnitOfWork (react-dom.development.js:26557:12) LoopSync di tempat kerja (react-dom.development.js:26466:5)
Saya percaya ini adalah isu HRM kerana ia seperti memuatkan seluruh halaman dengan hanya komponen kerana keadaan hilang dan maklumat tentang useMultisteps
hilang tetapi saya tidak dapat mencari jalan untuk menjadikannya berfungsi, tolong bantu Saya, ajar saya cara yang lebih baik untuk mencapai apa yang saya mahu lakukan
Apabila anda mengemas kini komponen, keadaan anda nampaknya hilang (mungkin kerana cangkuk useApp() kembali sebelum data sedia
null
).Cth. balut cangkuk useApp dalam cangkuk useMemo untuk memastikan ia dipanggil sekali sahaja:
Untuk meringkaskan, ini akan memastikan bahawa cangkuk useApp hanya dipanggil sekali dan nilai pulangannya diingati, walaupun komponen itu dipaparkan semula kerana HMR.
Cadangan kedua: cuba ubah suai kod anda seperti ini:
const { currentStep, next, back, isFirst } = data {};