我不确定标题是否正确,所以让我试着解释一下我试图实现的目标。
假设我的应用程序中有一个流,其中有3个步骤,所以我创建了一个包含3个子组件的组件(我们称之为Stepper
(,其中每个子组件都是呈现相应步骤的组件。
我想向Stepper
的子组件公开一个自定义钩子,我们称之为useStepper
。
这就是Stepper
的样子(JSX方面(:
export const Stepper = (props) => {
...some logic
return (
<SomeWrapper>
{props.children}
</SomeWrapper>
);
};
所以我可以制作这样的组件:
export SomeFlow = () => {
return (
<Stepper>
<StepOne />
<StepTwo />
<StepThree />
</Stepper>
);
};
现在,这就是我希望Stepper
的孩子们内部的工作方式,让我们以StepThree
为例:
export const StepThree = () => {
const exposedStepperData = useStepper();
... some logic
return (
...
);
};
现在,重要的是,Stepper
将是可重复使用的;这意味着,每个Stepper
实例都应该有自己的数据/状态/上下文,通过useStepper
钩子公开。不同的Stepper实例应该具有不同的公开数据。
有可能做到这一点吗?我尝试使用Context API,但没有成功。同样奇怪的是,我在互联网上找不到任何关于它的信息,也许我搜索错了查询,因为我不知道它是什么(如果存在的话(。
注意:
我通过从父对象到子对象的注入道具实现了类似的行为,但它并不像我希望的那样干净,尤其是使用Typescript。
我最近遇到了这样的事情,它是通过将所有组件/步骤倒在一个数组中并让钩子管理要显示的组件/步骤来解决的。如果您希望它更可重用,可以将children
传递给数组。
我希望这能帮助你朝着正确的方向
使用Stepper.ts
import { ReactElement, useState } from "react";
export const useStepper = (steps: ReactElement[]) => {
const [currentStepIndex, setCurrentStepIndex] = useState(0);
const next = () => {
setCurrentStepIndex((i: number) => {
if (i >= steps.length - 1) return i;
return i + 1;
});
};
const back = () => {
setCurrentStepIndex((i: number) => {
if (i <= 0) return i;
return i - 1;
});
};
const goTo = (index: number) => {
setCurrentStepIndex(index);
};
return {
currentStepIndex,
step: steps[currentStepIndex],
steps,
isFirstStep: currentStepIndex === 0,
isLastStep: currentStepIndex === steps.length - 1,
goTo,
next,
back,
};
};
步进.tsx
// const { currentStepIndex, step, isFirstStep, isLastStep, back, next } =
// useStepper([<StepOne />, <StepTwo />, <StepThree />]);
const { currentStepIndex, step, isFirstStep, isLastStep, back, next } =
useStepper([...children]);
return (
<div>
{!isFirstStep && <button onClick={back}>Back</button>}
{step}
<button onClick={next}>{isLastStep ? "Finish" : "Next"}</button>
</div>
);