React / Redux Saga: необходимо вызвать изменение маршрута после нажатия кнопки пользователем на форме - PullRequest
1 голос
/ 13 июня 2019

Я работаю над проектом, который был построен с использованием Redux Saga. У меня есть компонент, в котором есть группа предложений, каждая из которых имеет собственную кнопку для выбора конкретного предложения. Этот компонент находится на странице 1 из 4, и я пытаюсь выяснить, как вызвать перенаправление на следующую страницу после того, как пользователь нажмет выбор, но я понятия не имею, как это сделать в контексте Redux или Redux Saga. Я включил и обработчик навигации, и мой компонент ниже. Я начал редактировать компонент навигации с предложенным действием UPDATE_PAGE: , но я не уверен, что даже направляюсь по правильному пути. Буду очень признателен за любые предложения / объяснения или примеры кода о том, как это сделать

Offer Component

import React, { Fragment, Component } from 'react'
import PropTypes from 'prop-types'
import { connect } from 'react-redux'
import { Route, Switch, Redirect } from 'react-router-dom'
import styled from 'styled-components'
import NavigationContainer from '../../containers/NavigationContainer'
import RouteLoader from '../../components/core/RouteLoader'
import { getCustomer } from '../../actions/customer'
import { routerPropTypes, routePropTypes } from '../../propTypes'

class OrdersRoutes extends Component {
  static propTypes = {
    customer: PropTypes.object,
    getCustomer: PropTypes.func.isRequired,
    routes: routePropTypes,
    ...routerPropTypes
  }

  getAppData = data => {
    this.props.getCustomer(data)
  }

  render() {
    const { match, customer } = this.props
    const { offers: offersRoute, ...routes } = this.props.routes

    return (
      <Fragment>
        <Navigation>
          <Route
            path={match.path}
            component={NavigationContainer}
          />
        </Navigation>
        <PageContainer>
          <Switch>
            <RouteLoader
              exact
              path={`${match.path}${offersRoute.path}`}
              component={offersRoute.component}
              shouldLoad={customer !== undefined}
              onLoad={this.getAppData}
            />
            {Object.values(routes).map(
              ({
                path, id, component, disabled
              }) =>
                !disabled && (
                  <Route
                    exact
                    key={id}
                    path={`${match.path}${path}`}
                    component={component}
                  />
                )
            )}
            <Redirect to={`${match.path}${offersRoute.path}`} />
          </Switch>
        </PageContainer>
      </Fragment>
    )
  }
}

const Navigation = styled.div`
  padding: 0 10px;
`

const PageContainer = styled.div`
  padding: 0 20px;
  margin-top: 10px;
`

const mapStateToProps = state => ({
  routes: state.navigation.pages.orders.routes,
  customer: state.customer.details
})

const mapDispatchToProps = { getCustomer }

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(OrdersRoutes)

Navigation Component

import * as pages from '../constants/pages'

export const initialState = {
  pages: {
    ...pages
  }
}

function navigationReducer(state = initialState, { type, payload }) {
  switch (type) {
    UPDATE_PAGE: {
      const { id, page } = payload

      return {
        ...state,
        pages: {
          ...state.pages,
          [id]: {
            ...state.pages[id],
            ...page
          }
        }
      }
    }
    default: {
      return state
    }
  }
}

export default navigationReducer

1 Ответ

1 голос
/ 13 июня 2019

Хитрость заключается в том, чтобы включить историю реагирующего маршрутизатора в полезную нагрузку UPDATE_PAGE.

Итак 1) мы обертываем компонент, который запускает это действие с помощью Router. Это дает нам доступ к истории в качестве опоры; 2) при отправке UPDATE_PAGE включите историю в качестве полезной нагрузки в дополнение к идентификатору и странице 3) в redux-saga выполните перенаправление для каждого UPDATE_PAGE:

yield takeEvery(UPDATE_PAGE, function*(action){ action.payload.history.push('/new-route'); })
...