Как обрабатывать условную маршрутизацию или компонентную навигацию без React Router - PullRequest
0 голосов
/ 02 января 2019

Мне нужно перемещаться между компонентами на основе нескольких условий, и я не хочу, чтобы маршруты отображались в браузере, например localhost: 3000 / step1 или localhost: 3000 / step2. Все приложение ориентировано так, что пользователь должен ответить на все шаги для достижения конечного результата.

ATM У меня есть основной контейнер, который обрабатывает рендеринг компонента на основе значения хранилища Redux.

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);

Проблема в том, что я должен использовать диспетчеризацию для запуска навигации

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

почти во всех компонентах. У меня есть предопределенный JSON для каждого компонента, который содержит место назначения для каждого экрана.

screens : {
 SCREEN_A:{
  id: 1,
  name: 'SCREEN_A',
  next: 'SCREEN_B',
  back: 'WELCOME_SCREEN',
  activeLoader: true,
 },
 SCREEN_B:{
  id: 2,
  name: 'SCREEN_B',
  next: 'SCREEN_C',
  back: 'WELCOME_SCREEN',
  activeLoader: true,
 },
 SCREEN_C:{
  id: 3,
  name: 'SCREEN_C',
  next: 'SCREEN_D',
  back: 'SCREEN_A',
  activeLoader: true,
 },
 SCREEN_D:{
  id: 4,
  name: 'SCREEN_D',
  next: 'SCREEN_E',
  back: 'SCREEN_D',
  activeLoader: true,
 },
}

И есть защищенные экраны, которые усложняют ситуацию. Есть ли лучший способ сделать это с редуксом? или я должен создать промежуточное программное обеспечение и перехватывать каждое изменение состояния и вычислять следующий экран.

1 Ответ

0 голосов
/ 02 января 2019

Я бы изменил несколько вещей:

  1. Сделайте ваши шаги / экраны динамическими. Помещая их в массив и используя индекс для определения текущего шага, он удаляет много кода и упростит добавление / перемещение шагов.

  2. Сохраните конфигурацию шагов / экранов в хранилище приставок.

  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 });
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...