如何激活受访步骤?

问题描述

我正在制作一个简单的react应用程序,并包含react-stepper-horizontal库,一切正常。

工作示例:

Edit next-dynamic-testing-issue (forked)

与步进相关的适当代码:

const Form = () => {
.
.
.

const [currentPage,setCurrentPage] = useState(1);
const sections = [
  { title: 'Basic Details',onClick: () => setCurrentPage(1) },{ title: 'Employment Details',onClick: () => setCurrentPage(2) },{ title: 'Review',onClick: () => setCurrentPage(3) },];
    
<Stepper
  steps={sections}
  activeStep={currentPage}
  activeColor="red"
  defaultBarColor="red"
  completeColor="green"
  completeBarColor="green"
/>

.
.
.
}

重现问题的步骤:

->共有三个步骤1,2,3,每个步骤分别具有不同的部分,分别为Basic DetailsEmployment DetailsReview

->现在,如果用户在步骤1中输入任何一个输入字段,然后转到步骤2并在其中填写一些输入字段,然后转到步骤3进行检查,如果他再次返回到步骤1,则处于活动状态在步骤3中丢失。

->因此,现在问题是如果我们要转到步骤3,则需要再次走三步才能到达最后的步骤3。

要求:

->如果用户曾经访问过任何步骤,那么如果他访问了先前的任何步骤,那么他先前访问的所有步骤都必须处于活动状态。

例如:

->如果用户进入Step 1,然后使用下一步按钮,他将到达Step 3,并且如果他希望返回Step 1来修改一些输入,并且如果他想转到Step 3进行审核,那么应该可以通过单击Step 3,因为他已经访问了该步骤。

请帮助我获得使用户访问的步骤处于活动状态的结果。如果用户访问步骤3并单击“步骤1”圆圈返回到步骤1,则应该有可能返回再次访问步骤3,因为他已经访问了步骤3。

也欢迎任何没有任何库的解决方案。

如果我们还有更多步骤(例如7个步骤),这将是一个大问题。所以,请您帮我。。在此先感谢您。

解决方法

这是所讨论的<Stepper />组件的简单实现。关键是要有一个tracker来内部跟踪所访问的步骤,并在重新渲染时保留该信息。

Demoboard Playground

const { useState,useEffect,useMemo } = React;
const cx = classNames;

function range(a,b) {
  return new Array(Math.abs(a - b) + 1).fill(a).map((v,i) => v + i);
}

function Stepper({ steps,activeStep,children }) {
  const count = steps.length;
  const listOfNum = useMemo(() => range(1,count),[count]);
  const tracker = useMemo(() => {
    let highestStep = 0;

    function hasVisited(step) {
      return highestStep >= step;
    }

    function addToBackLog(step) {
      if (step > highestStep) highestStep = step;
    }

    return {
      hasVisited,addToBackLog,getHighestStep() {
        return highestStep;
      },};
  },[]);

  tracker.addToBackLog(activeStep);

  const noop = () => {};

  const prevStep = steps[activeStep - 2];
  const currentStep = steps[activeStep - 1];
  const nextStep = steps[activeStep];

  return (
    <div>
      <div>
        {" "}
        {listOfNum.map((num,i) => {
          const isActive = activeStep == num;
          const isVisited = tracker.hasVisited(num);
          const isClickable = num <= tracker.getHighestStep() + 1 || isVisited;
          return (
            <div
              key={num}
              className={cx("circle",{
                active: isActive,visited: isVisited,clickable: isClickable,})}
              onClick={isClickable ? steps[i].onClick : noop}
            >
              {num}{" "}
            </div>
          );
        })}{" "}
      </div>{" "}
      <h2> {currentStep && currentStep.title} </h2> <div> {children} </div>{" "}
      <div className="footer">
        {" "}
        {prevStep ? (
          <button onClick={prevStep.onClick}> prev </button>
        ) : null}{" "}
        {nextStep ? <button onClick={nextStep.onClick}> next </button> : null}{" "}
      </div>{" "}
    </div>
  );
}

function App() {
  const [currentPage,setCurrentPage] = useState(1);
  const sections = [
    {
      title: "Un",onClick: () => setCurrentPage(1),},{
      title: "Deux",onClick: () => setCurrentPage(2),{
      title: "Trois",onClick: () => setCurrentPage(3),{
      title: "Quatre",onClick: () => setCurrentPage(4),{
      title: "Cinq",onClick: () => setCurrentPage(5),];

  return (
    <Stepper steps={sections} activeStep={currentPage}>
      I 'm page {currentPage}{" "}
    </Stepper>
  );
}

ReactDOM.render(<App />,document.getElementById("root"));
body {
  color: #0f0035;
  padding-bottom: 2rem;
}

.circle {
  display: inline-flex;
  height: 2em;
  width: 2em;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background-color: lightgrey;
  margin: 0 0.5em;
  color: white;
  cursor: not-allowed;
}

.active {
  background-color: rgba(50,50,250) !important;
}

.visited {
  background-color: rgba(50,250,0.5);
}

.clickable {
  cursor: pointer;
}

.footer {
  margin-top: 1em;
  display: flex;
  justify-content: space-between;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/classnames/2.2.6/index.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.0/umd/react-dom.production.min.js"></script>
<div id="root"></div>

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...