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'); })
我正在开发一个使用 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'); })