我正在尝试创建一个多步骤表单,我将数据放在一个单独的文件中,用于这样的常量
从“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 上的信息丢失,但我只是找不到一种方法来实现它工作,请帮助我,教我更好的方法来完成我想做的事情
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
当您更新组件时,您的状态似乎丢失了(可能是因为 useApp() 挂钩在数据准备好之前返回
null)。例如将 useApp 挂钩包装在 useMemo 挂钩中,以确保它只被调用一次:
总而言之,这将确保 useApp 挂钩仅被调用一次,并且它的返回值会被记忆,即使组件由于 HMR 而重新渲染也是如此。
第二个建议:尝试修改您的代码,如下所示:
const { currentStep, next, back, isFirst } = 数据 ?? {};
这将确保解构操作仅在数据对象不为空时发生。