首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >React路由器:如何将新组件和路由添加到向导的入职步骤中?

React路由器:如何将新组件和路由添加到向导的入职步骤中?
EN

Stack Overflow用户
提问于 2019-07-05 16:01:16
回答 2查看 319关注 0票数 2

我正在使用的这个项目有一个入职向导,基本上是一些代码来处理一步一步的入职过程,几乎与您在这里看到的类似:

e/writing-a-wizard-in-react-8dafbce6db07

除了这个功能外,它还应该具有将组件或步骤转换为路由的功能:

代码语言:javascript
复制
convertStepToRoute = step => {
    const Component = StepComponents[step.component || ''];

    return Component
      ? <Route
          key={step.key}
          path={`${WizardLayout.pathname}/${step.url}`}
          render={this.renderRouteComponent(Component)}
        />
      : null;
  };

StepComponents来自import StepComponents from '../Steps';,它是一个包含所有组件的目录,现在只有六个,其中七个应该带用户完成入职过程。

我的理解是,它们是从index.js目录中的Steps/文件中提取出来的,类似于还原器文件夹中的根还原器文件来导出所有这些文件,本例中的步骤组件如下所示:

代码语言:javascript
复制
import glamorous from "glamorous";
import ThemedCard from "../../ThemedCard";
import BusinessAddress from "./BusinessAddress";
import CreatePassword from "./CreatePassword";
import GetInvolved from "./GetInvolved";
import Representatives from "./Representatives";
import Topics from "./Topics";
import MemberBenefits from "./MemberBenefits";

export const StepHeader = glamorous.div({
  marginBottom: 20,
  marginTop: 20,
  fontSize: "2rem",
  color: "#757575"
});

const OnboardingCompleted = glamorous(ThemedCard)({
  textAlign: "center",
  boxShadow: "none !important"
});

export default {
  CreatePassword,
  BusinessAddress,
  Completed: OnboardingCompleted,
  GetInvolved,
  MemberBenefits,
  Topics,
  Representatives
};

嗯,我添加了我的MemberBenefits,它似乎不起作用,它没有用相应的路径进行渲染。它在哪里不能注册这个新的步骤或组件?

好吧,魔法不是在Onboarding/OnBoardingWizard/index.js里面发生的,它发生在Wizard/WizardEngine.js里面

代码语言:javascript
复制
import React from "react";
import PropTypes from "prop-types";
import objectToArray from "../../../../common/utils/object-to-array";

// TODO: figure out how to use this without making children of wizard engine tied to wizardStep
// eslint-disable-next-line no-unused-vars
class WizardStep {
  constructor({ component, color, order, render }, stepComponents) {
    if (!component || !render) {
      throw new Error("Component or render must be provided.");
    }

    let componentValue;
    if (component) {
      componentValue = this.resolveComponent(component, stepComponents);
      if (!!componentValue && !React.isValidElement(componentValue)) {
        throw new Error(
          "wizard step expected component to be a valid react element"
        );
      }
    } else if (render && typeof render === "function") {
      throw new Error("wizard step expected render to be a function");
    }

    this.Component = componentValue;
    this.color = color;
    this.order = order;
    this.render = render;
  }

  resolveComponent = (component, stepComponents) => {
    const componentValue = component;

    if (typeof component === "string") {
      const componentValue = stepComponents[component];
      if (!componentValue) {
        throw new Error("component doesnt exist");
      }
    }

    return componentValue;
  };
}

export default class WizardEngine extends React.Component {
  static propTypes = {
    steps: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
    initActiveIndex: PropTypes.oneOfType([PropTypes.func, PropTypes.number]),
    stepComponents: PropTypes.object
  };

  constructor(props) {
    super(props);
    this.state = {
      activeIndex: this.resolveInitActiveIndex(props),
      steps: this.buildStepsFromConfig(props)
    };
  }

  componentWillReceiveProps(nextProps) {
    this.setState({ steps: this.buildStepsFromConfig(nextProps) });
  }

  resolveInitActiveIndex = props => {
    const { initActiveIndex } = props;
    let activeIndex = 0;

    if (typeof initActiveIndex === "function") {
      activeIndex = initActiveIndex(props);
    }

    if (typeof initActiveIndex === "number") {
      activeIndex = initActiveIndex;
    }

    return activeIndex;
  };

  buildStepsFromConfig = props => {
    const { steps } = props;
    let stepArr = steps;

    // validate stepList
    if (typeof steps === "object" && !Array.isArray(steps)) {
      stepArr = objectToArray(steps);
    }

    if (!Array.isArray(stepArr)) {
      throw new Error(
        `Unsupported Parameter: Wizard Engine(steps) expected either (object, array); got ${typeof stepArr}`
      );
    }

    return stepArr;

    // return stepArr.map(step => new WizardStep(step));
  };

  setActiveIndex = activeIndex => {
    this.setState({ activeIndex });
  };

  goForward = () => {
    this.setState(prevState => ({
      activeIndex: prevState.activeIndex + 1
    }));
  };

  goBack = () => {
    this.setState(prevState => ({
      activeIndex: prevState.activeIndex - 1
    }));
  };

  render() {
    const { children } = this.props;
    const childProps = {
      ...this.state,
      setActiveIndex: this.setActiveIndex,
      goForward: this.goForward,
      goBack: this.goBack,
      currentStep: this.state.steps[this.state.activeIndex]
    };

    if (Array.isArray(children)) {
      return (
        <div>
          {children.map((child, i) => {
            if (typeof child === "function") {
              return child(childProps);
            }
            childProps.key = `${child.type.name}_${i}`;
            return React.cloneElement(child, childProps);
          })}
        </div>
      );
    }

    if (typeof children === "function") {
      return children(childProps);
    }

    return children;
  }
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-07-07 16:07:10

使用实体框架( Entity )将路径URL映射到后端,类似于在本文档中可以在这里查看的设置:

https://dzone.com/articles/aspnet-core-crud-with-reactjs-and-entity-framework

只不过是用快递的。

因此,在传统意义上,它不使用React路由器,在这种情况下,Express允许它控制到组件的整个映射路径,而是在Express src/app-server/apiConfig.js中映射到入职组件的路径,如下所示:

代码语言:javascript
复制
"get-involved-onboarding": {
      title: "Get Involved",
      url: "/account/onboarding/get-involved",
      icon: "explore",
      component: "GetInvolved",
      progress: {
        stepType: "GetInvolved",
        hasCompleted: true
      }
    },
票数 1
EN

Stack Overflow用户

发布于 2019-07-05 16:14:47

我认为第一个方法只在需要时加载元素。第二个方法每次加载所有方法。当你在/Products时,为什么要加载回家?

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56906235

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档