reactjs - Snabb uppdatering misslyckas vid dynamisk import av komponenter i Vite med React och TypeScript
Jag försöker skapa ett flerstegsformulär, jag har mina data i en separat fil för konstanter som detta
import { lazy } from 'react';
export const steps = [
{
id: 0,
name: 'Personal Info',
component: lazy(() => import('../components/PersonalInfo')),
},
];
Jag skickar det till en anpassad hook i ett sammanhang
const dataSteps = useMultiStep(steps);
const { next, back, currentStep, isFirst } = dataSteps;
Detta är customhooken
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;
Jag använder de dynamiska komponenterna här
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;
Min vite-konfiguration är denna
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
});
Efter att ha försökt ALLT får jag fortfarande dessa fel, inte vid de första renderingarna utan när komponenten laddas om
App.tsx:7 Ohanterat TypeError: Kan inte destrukturera egenskapen 'currentStep' från 'data' eftersom den är null. vid App (App.tsx:7:11) vid renderWithHooks (react-dom.development.js:16305:18) vid mountIndeterminateComponent (react-dom.development.js:20074:13) vid beginWork (react-dom.development.js:21587:16) vid HTMLUnknownElement.callCallback2 (react-dom.development.js:4164:14) vid Object.invokeGuardedCallbackDev (react-dom.development.js:4213:16) vid invokeGuardedCallback (react-dom.development.js:4277:31) vid beginWork$1 (react-dom.development.js:27451:7) vid performUnitOfWork (react-dom.development.js:26557:12) vid workLoopSync (react-dom.development.js:26466:5)
Jag tror att det är ett HRM-problem eftersom det är som att ladda hela sidan istället för bara komponenten, och därför förloras tillstånden och informationen i useMultisteps förloras, men jag kan bara inte hitta ett sätt att få det att fungera, snälla hjälp mig eller lär mig ett bättre sätt att uppnå det jag försöker göra
Svar #1
Det verkar som att ditt tillstånd går förlorat när du uppdaterar komponenten (troligtvis eftersom useApp()-hooken returnerar null innan datan är redo).
- Försök att omsluta den stateful komponenten i en React memo(). På detta sätt bevaras komponentens tillstånd över HMR-uppdateringar.
t.ex. wrappa useApp-hooken i useMemo-hooken för att säkerställa att den bara anropas en gång:
const data = useMemo(() => useApp(), []);
För att sammanfatta kommer detta att säkerställa att useApp-hooken endast anropas en gång och att dess returvärde memoriseras, även om komponenten renderas om på grund av HMR.
andra förslaget: försök att ändra din kod som nedan:
const { currentStep, next, back, isFirst }=data ?? {};
Detta kommer att säkerställa att destruktureringen endast sker om dataobjektet inte är null.
