我正在尝试为表单提交创建垂直步进器。 useEffect的setpersState(stepState);内部的Stepper.jsx中存在一个问题。程序连续运行
当我从useEffect中删除依赖项列表时,它会正常运行,但不会传递更新值。
这是codeandbox链接codesanbok
import React, { useState, useEffect } from "react";
import PropTypes from "prop-types";
import "./Stepper.scss";
const Stepper = ({
stepColor,
steps,
direction,
currentStep,
setStepsState
}) => {
const [stepState, setStepState] = useState([]);
useEffect(() => {
let createSteps = steps.map((step, idx) => ({
description: step.label,
component: step.component,
completed: idx < currentStep - 1, // past are completed
selected: idx <= currentStep - 1, // past & present are colored
highlighted: idx === currentStep - 1 // only present is highlighted
}));
setStepState(createSteps);
}, [steps, currentStep]);
useEffect(() => {
if (stepState) setStepsState(stepState);
}, [stepState]);
return (
<>
<div className={`stepper-wrapper-${direction}`}>
{stepState.map(
(
{ selected, completed, highlighted, description, component },
idx
) => (
<div className="step-wrapper" key={idx}>
<div
className={`step-number step-number-${
selected ? "active" : "disabled"
}`}
style={{ background: `${selected ? stepColor : "none"}` }}
>
{completed ? "✔" : idx + 1}
</div>
<div
className={`step-description ${
highlighted ? "step-description-active" : ""
}`}
>
{description}
</div>
{idx + 1 !== stepState.length && (
<div
className={`divider-line divider-line-${stepState.length}`}
/>
)}
</div>
)
)}
</div>
</>
);
};
Stepper.propTypes = {
direction: PropTypes.string.isRequired,
steps: PropTypes.array.isRequired
};
export default Stepper;
答案 0 :(得分:1)
以下内容完全没有意义:
useEffect(() => {
if (stepState) setStepsState(stepState);
}, [stepState]);
您将setStepsState
作为prop传递,并将其定义为本地状态设置器。
在沙箱中,您可以在App和Step中复制逻辑和状态,并使用App或Step来添加逻辑,而不能同时使用逻辑。
以下是在App中维护逻辑和状态的示例:
const { useEffect, useState } = React;
const Stepper = ({ steps }) => {
return <pre>{JSON.stringify(steps, undefined, 2)}</pre>;
};
const steps = [
{ label: 'step 1', component: 'component 1' },
{ label: 'step 2', component: 'component 2' },
{ label: 'step 3', component: 'component 3' },
];
const createSteps = (currentStep) =>
steps.map((step, idx) => ({
description: step.label,
component: step.component,
completed: idx < currentStep - 1, // past are completed
selected: idx <= currentStep - 1, // past & present are colored
highlighted: idx === currentStep - 1, // only present is highlighted
}));
const App = () => {
const [currentStep, setCurrentStep] = React.useState(1);
const [stepsState, setsStepState] = useState(
createSteps(currentStep)
);
useEffect(() => {
setsStepState(createSteps(currentStep));
}, [currentStep]);
return (
<div>
<button
onClick={() => setCurrentStep(currentStep + 1)}
>
next step
</button>
<Stepper steps={stepsState} />
</div>
);
};
ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="root"></div>