如何在没有React Router的情况下处理条件路由或组件导航

时间:2019-01-02 15:54:55

标签: reactjs react-redux

我需要根据几种条件在组件之间导航,并且我不想在浏览器中显示路由,例如localhost:3000 / step1或localhost:3000 / step2。指导整个应用程序,以便用户必须回答所有步骤才能达到最终结果。

ATM我有一个主容器,该容器根据Redux存储值处理组件渲染。

var tables = await Task.WhenAll(result);

问题是我必须使用分派来触发导航

import React, { Component } from "react";
class Home extends Component {
  renderComponent = screen => {
    switch (screen) {
     case 'SCREEN_A':
      return <ScreenA />;

     case 'SCREEN_B':
      return <ScreenB />;

     case 'SCREEN_C':
      return <ScreenC />;

     case 'SCREEN_D':
      return <ScreenD />;

     default:
      return <ScreenA />;
   }
  };

  render() {
    return <div>{this.renderComponent(this.props.currentScreen)}</div>;
  }
}

function mapStateToProps(storeData) {
  return {
    store: storeData,
    currentScreen: storeData.appState.currentScreen,
    userData: storeData.userData
 };
}
export default connect(mapStateToProps)(Home);

几乎所有组件。对于每个组件,我确实都有一个预定义的JSON,其中包含每个屏幕的目标。

navigateTo(screens[destination])
navigateBackward(currentScreen)
navigateForward(currentScreen)

并且有受保护的屏幕,这使事情变得更加复杂。有没有更好的办法用redux做到这一点?还是应该创建一个中间件并拦截每个状态更改并计算下一个屏幕。

1 个答案:

答案 0 :(得分:1)

我会改变几件事:

  1. 使您的步骤/屏幕动态化。通过将它们放入数组并使用索引确定当前步骤,它可以删除大量代码,并使添加/移动步骤更加容易。

  2. 将步骤/屏幕配置存储在redux存储中。

  3. (可选)您可以将nextStep和previousStep传递给StepComponent。例如<StepComponent nextStep={nextStep} previousStep={previousStep} />

在最后一步中,您可能想调用其他操作,而不是nextStep。

这就是我的解决方案:

// Home.jsx
import React, { Component } from 'react';
import * as types from '../../redux/Actor/Actor.types';

class Home extends Component {
  stepComponents = [
    ScreenA,
    ScreenB,
    ScreenC,
    ScreenD,
  ];

  render() {
    const { step, steps } = this.props;

    const StepComponent = this.stepComponents[step];

    return (
      <div>
        <StepComponent {...steps[step]} />
      </div>
    );
  }
}

// store.jsx
export default {
  step : 0,
  steps: [
    {
      id          : 1,
      name        : 'SCREEN_A',
      activeLoader: true,
    },
    ....
  ],
};

// actions.jsx
export const nextStep = () => ({ type: 'NEXT_STEP' });
export const previousStep = () => ({ type: 'PREVIOUS_STEP' });

// reducers.jsx
export const nextStep = state => ({ ...state, step: state.step + 1 });
export const previousStep = state => ({ ...state, step: state.step - 1 });