Ich versuche ein mehrstufiges Formular zu erstellen und füge die Daten für Konstanten wie diese in eine separate Datei ein
{lazy} aus „reagieren“ importieren
export const steps = [ { id: 0, name: 'Personal Info', component: lazy(() => import('../components/PersonalInfo')), }, ];
Ich übergebe es an einen benutzerdefinierten Hook im Kontext
const dataSteps = useMultiStep(steps); const { next, back, currentStep, isFirst } = dataSteps;
Dies ist ein individueller Haken
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;
Ich verwende hier dynamische Komponenten
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;
Meine Vite-Konfiguration ist so
import { defineConfig } from 'vite'; import react from '@vitejs/plugin-react'; // https://vitejs.dev/config/ export default defineConfig({ plugins: [react()], });
Nachdem ich alles versucht habe, erhalte ich immer noch diesen Fehler, nicht beim ersten Rendern, sondern beim Neuladen der Komponente
App.tsx:7 Nicht abgefangener TypeError: Die Eigenschaft „currentStep“ von „data“ kann nicht zerstört werden, da sie null ist. In der Anwendung (App.tsx:7:11) in renderWithHooks (react-dom.development.js:16305:18) in mountInminatedComponent (react-dom.development.js:20074:13) Zu Beginn der Arbeit (react-dom.development.js:21587:16) bei HTMLUnknownElement.callCallback2 (react-dom.development.js:4164:14) bei Object.invokeGuardedCallbackDev (react-dom.development.js:4213:16) in invokeGuardedCallback (react-dom.development.js:4277:31) bei beginWork$1 (react-dom.development.js:27451:7) in PerformUnitOfWork (react-dom.development.js:26557:12) LoopSync bei der Arbeit (react-dom.development.js:26466:5)
Ich glaube, das ist ein HRM-Problem, weil es so ist, als würde man die gesamte Seite nur mit den Komponenten laden, weil der Status verloren geht und die Informationen zu useMultisteps
verloren gehen, aber ich finde einfach keine Möglichkeit, es zum Laufen zu bringen. Bitte helfen Sie mir, lehren Sie mich Ich habe bessere Möglichkeiten, das zu erreichen, was ich tun möchte
当您更新组件时,您的状态似乎丢失了(可能是因为 useApp() 挂钩在数据准备好之前返回
null
)。例如将 useApp 挂钩包装在 useMemo 挂钩中,以确保它只被调用一次:
总而言之,这将确保 useApp 挂钩仅被调用一次,并且它的返回值会被记忆,即使组件由于 HMR 而重新渲染也是如此。
第二个建议:尝试修改您的代码,如下所示:
const { currentStep, next, back, isFirst } = 数据 ?? {};
这将确保解构操作仅在数据对象不为空时发生。