我正在从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工具时,它表示page
和content
未定义。我在重构时在InfoPage组件上更改的唯一内容是添加match.params
而不是params
。这让我相信我的Redux / Router集成有问题,特别是ownProps/routeProps
没有正确传递。
关于这里有什么问题的任何想法?
答案 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)
)
毕竟,如果您发现page
和content
仍然是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
...并确认您已通过page
将combineReducers
缩减器传递到您的商店:
import pageReducer from '../reducers/page'
const rootReducer = combineReducers({
page: pageReducer,
})
const store = configureStore(
rootReducer,
/* store middlewares, etc */
)
export default store