React/Redux Saga:需要在用户单击表单上的按钮后触发路由更改

React/Redux Saga: Need to trigger a route change after user clicks button on form

我正在开发一个使用 Redux Saga 构建的项目。我有一个组件,其中包含一组优惠,每个优惠都有自己的按钮 select 该特定优惠。该组件位于第 1 页,共 4 页,我试图弄清楚如何在用户单击 selection 后触发到下一页的重定向,但我不知道如何在Redux 或 Redux Saga。我在下面包含了导航处理程序和我的组​​件。我开始使用建议的操作 UPDATE_PAGE: 来编辑导航组件,但我不确定我是否正朝着正确的方向前进。任何有关如何执行此操作的 suggestions/explanations 或代码示例将不胜感激

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

诀窍是将 react-router 的历史记录包含到 UPDATE_PAGE 的有效载荷中。

所以 1) 我们用 Router 包装一个触发这个动作的组件。这使我们能够访问历史作为道具; 2) 在调度 UPDATE_PAGE 时,除了 id 和页面之外,还包括历史作为有效负载 3) 在 redux-saga 中对每个 UPDATE_PAGE:

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