如何基于Redux选中的面试步骤动态填充MUI垂直Stepper的steps数组?
实现动态生成MUI垂直Stepper步骤的最佳方式
核心思路
基于Redux中interviewStep1、interviewStep2、interviewStep3的实际选择值,动态构建steps数组:只保留有有效内容的面试步骤,最后固定添加"Offer"步骤。同时用useMemo缓存生成结果,避免不必要的重渲染。
具体实现步骤
1. 动态构建steps数组
使用useMemo根据Redux状态生成steps,过滤掉未选择的步骤:
const steps = React.useMemo(() => { // 收集有效面试步骤 const interviewSteps = []; if (interviewStep1) { interviewSteps.push({ label: interviewStep1 }); } if (interviewStep2) { interviewSteps.push({ label: interviewStep2 }); } if (interviewStep3) { interviewSteps.push({ label: interviewStep3 }); } // 固定添加Offer步骤 return [...interviewSteps, { label: 'Offer' }]; }, [interviewStep1, interviewStep2, interviewStep3]);
2. 修正步骤切换逻辑
因为steps是动态的,需要调整handleNext的边界判断,防止activeStep超出数组长度:
const handleNext = () => { setActiveStep((prev) => Math.min(prev + 1, steps.length - 1)); };
3. 调整Stepper渲染细节
- 动态判断"Last step"标记:只有当当前步骤是最后一个(即Offer步骤)时显示
- 按钮文字可以根据是否是最后一步调整(比如最后一步显示"完成"而不是"Continue")
修改后的完整代码
export default function JobPostInterviewVerticalStepper() { const [activeStep, setActiveStep] = React.useState(0); const interviewStep1 = useSelector(state => state.jobsearch.selectedInterview1) const interviewStep2 = useSelector(state => state.jobsearch.selectedInterview2) const interviewStep3 = useSelector(state => state.jobsearch.selectedInterview3) const handleNext = () => { setActiveStep((prev) => Math.min(prev + 1, steps.length - 1)); }; const handleBack = () => { setActiveStep((prevActiveStep) => prevActiveStep - 1); }; const handleReset = () => { setActiveStep(0); }; // 动态生成steps数组 const steps = React.useMemo(() => { const interviewSteps = []; if (interviewStep1) { interviewSteps.push({ label: interviewStep1 }); } if (interviewStep2) { interviewSteps.push({ label: interviewStep2 }); } if (interviewStep3) { interviewSteps.push({ label: interviewStep3 }); } return [...interviewSteps, { label: 'Offer' }]; }, [interviewStep1, interviewStep2, interviewStep3]); return ( <Wrapper> <Stepper activeStep={activeStep} orientation="vertical"> {steps.map((step, index) => ( <Step key={step.label}> <StepLabel optional={ index === steps.length - 1 ? ( <Typography fontSize="12px" >Last step</Typography> ) : null } > {step.label} </StepLabel> <StepContent> <Box sx={{ mb: 1 }}> <div> <Button variant="contained" onClick={handleNext} sx={{ mt: .5, mr: .5 }} > {index === steps.length - 1 ? '完成' : '继续'} </Button> <Button disabled={index === 0} onClick={handleBack} sx={{ mt: 1, mr: 1 }} > 返回 </Button> </div> </Box> </StepContent> </Step> ))} </Stepper> </Wrapper> ); }
额外优化点
- 如果所有面试步骤都未选择,steps会只有"Offer"一步,可以添加默认提示(比如在Offer步骤前显示"请选择面试步骤"),根据需求调整
- 可以给每个步骤添加额外属性(比如描述、图标),根据Redux中存储的扩展数据动态生成
内容的提问来源于stack exchange,提问作者n_d22
相关产品推荐
相关产品推荐

