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

时间:2019-06-13 01:56:18

标签: javascript reactjs validation redux-saga react-hooks

我正在使用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 个答案:

答案 0 :(得分:1)

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

因此1)我们包装了一个组件,该组件使用Router触发此操作。这使我们能够以历史为支柱。 2)调度UPDATE_PAGE时,除了id和page之外,还包括历史记录作为有效载荷3)在redux-saga中,对每个UPDATE_PAGE进行重定向:

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