OwnProps没有与React Router V4一起传递

时间:2017-11-17 22:42:05

标签: reactjs redux react-router react-redux

我正在从React Router的V2到V4重构应用程序,我遇到了一个问题,即mapStateToProps的属性没有传递给每个组件。这是我的设置:

App.jsx

render() {
        return (
            <div>
                <Header />
                <Navbar />
                <Routes {...this.props} />
                <Footer />
            </div>
        )
    }

const mapStateToProps = (state, ownProps) => {
    const { page } = state
    return {
        routeProps: ownProps,
        page: page
    }
}

const mapDispatchToProps = (dispatch) => {
    return {
        pageActions: bindActionCreators(pageActionCreators, dispatch),
    }
}

export default withRouter(connect(mapStateToProps, mapDispatchToProps)(App))

Routes.jsx有这一行:

<Route exact path="/:name/information" render={ ({ match }) => <InfoPage {...this.props} match={ match } /> } />

InfoPage.jsx

componentDidMount() {
    const { routeProps, pageActions } = this.props
    pageActions.fetchInfoPage(routeProps.match.params.name)
}
componentWillReceiveProps(nextProps) {
    if (this.props.page.page !== nextProps.page.page) {
        const { routeProps, pageActions } = nextProps
        pageActions.fetchInfoPage(routeProps.match.params.name)
    }
}
render() {
    return (
        <InfoPageView
        page={ this.props.page }
        pageActions={ this.props.pageActions }
        routeProps={ this.props.routeProps }
        />
    )
}

问题在于,当我尝试访问使用InfoPage的路由时,即/orders/information,它永远不会加载。当我检查Redux dev工具时,它表示pagecontent未定义。我在重构时在InfoPage组件上更改的唯一内容是添加match.params而不是params。这让我相信我的Redux / Router集成有问题,特别是ownProps/routeProps没有正确传递。

关于这里有什么问题的任何想法?

2 个答案:

答案 0 :(得分:1)

您可以尝试将withRouter电话转移到Routes.jsx

export default withRouter(connect()(Routes))

我认为需要与任何<Route ... />组件位于同一个文件中。

答案 1 :(得分:1)

首先,确保您正在包装version: "2" services: app: container_name: someappname restart: always build: . ports: - "6085:6085" links: - mongo depends_on: - mongo mongo: container_name: mongo image: mongo volumes: - ./tmp:/data/db ports: - "27017:27017" (正如@lemarc和@Kyle Richardson之前提到的那样),以便您的路由组件能够正确更新。

当您使用Routes.jsx打包已连接的组件时,它会在该组件的props中提供withRouter

您可以通过match的包装组件访问match,而不是尝试通过ownProps映射props

此外,您似乎正在尝试引用与您的子组件App中的InfoPageView组件绑定的Action Creator。这是React + Redux应用程序中的反模式。

如果您的InfoPageView需要能够发送操作,则应直接通过自己的InfoPageView函数将其提供给mapDispatchToProps。您尝试访问的page属性也是如此;如果InfoPageView需要阅读page的值,则应通过mapStateToProps直接提供:

import { Component } from 'react'
import { connect, bindActionCreators } from 'react-redux'
import { withRouter } from 'react-router'
import { fetchInfoPage as fetchInfoPageAction } from '../actions/fetchInfoPage'
// ^ import directly from wherever this Action Creator resides in your project ^

class InfoPageView extends Component {
    componentDidMount() {

        const { match } = this.props
        fetchInfoPage(match.params.name) // <-- `match` provided by withRouter()

    }

    componentWillReceiveProps(nextProps) {

        if (this.props.page.page !== nextProps.page.page) {
            const { match, fetchInfoPage } = nextProps
            fetchInfoPage(match.params.name) // <-- `match` provided by withRouter()
        }

    }
    render() {

        return (
            <InfoPageView />
        )

    }

}

const mapStateToProps = (state) => ({
   page: state.page,
   content: state.content,
})
const mapDispatchToProps = (dispatch) => ({
    fetchInfoPage: bindActionCreators(fetchInfoPageAction, dispatch),
})

export default withRouter(
    connect(mapStateToProps, mapDispatchToProps)(InfoPageView)
)

毕竟,如果您发现pagecontent仍然是undefined,那么他们{{1}可能只是遗漏了page减速器。验证page缩减器initialState中是否存在这些属性:

const initialState = { page: 1, content: 'initial content' }

const page = (state = initialState, action) => ({
    switch (action.type) {

        // (action type `case` statements here)

        default:
            return state
    }
})

export default page

...并确认您已通过pagecombineReducers缩减器传递到您的商店:

import pageReducer from '../reducers/page'

const rootReducer = combineReducers({
  page: pageReducer,
})

const store = configureStore(
  rootReducer,
  /* store middlewares, etc */
)

export default store