我在react / redux中相当初学者,我正在使用React,Redux和React Router v4创建一个简单的项目。我使用Redux来处理状态,它成功地将状态传递给根组件Wrapper,但似乎它没有将它传递给Home或其他组件。 当我在Wrapper中登录this.props.Gallery时,会显示数据,但是当我在Gallery上显示时,它会显示“未定义”。我使用React.cloneElement在Wrapper中传递了孩子,但它没有用。是否有解释和一些解决方法?
我的应用项目结构是
--wrapper
-home
-gallery
-about
-links
以下是组件
用于路由 App.js
import React from 'react'
import ReactDOM from 'react-dom'
import { BrowserRouter, Route, Switch } from 'react-router-dom'
import Wrapper from './components/Wrapper';
...
//import store
import {Provider} from 'react-redux'
import store , {history} from './store'
//router
const mainRouter=(
<Provider store={store} history={history}>
<Wrapper>
<BrowserRouter>
<Switch>
<Route exact path='/' component={ Home } />
<Route path='/portfolio' component={ Gallery } />
<Route path='/about' component={ About } />
<Route path='/links' component={ Links } />
</Switch>
</BrowserRouter>
</Wrapper>
</Provider>
)
ReactDOM.render(mainRouter, document.getElementById('root'))
包装
import React from 'react'
import {bindActionCreators} from 'redux'
import {connect} from 'react-redux'
import * as actionCreators from '../actions/actionCreators'
function mapStateToProps(state){
return{
gallery:state.gallery
}
}
function mapDispatchToProps(dispatch){
return bindActionCreators(actionCreators,dispatch)
}
class Wrapper extends React.Component{
render(){
return(
<div>
{React.cloneElement(this.props.children, this.props)}
</div>
)
}
}
export default connect(
mapStateToProps,
mapDispatchToProps
)(Wrapper)
Home.js
import React from 'react'
import { NavLink } from 'react-router-dom'
//import component
...
class Home extends React.Component {
render(){
console.log(this.props.gallery)
return(
<div>
<p>this is home page</p>
<Header/>
<Nav/>
<Footer/>
</div>
)
}
}
export default Home;
更新9/19 我设法在react路由器v4中创建了嵌套组件,但仍然无法将props传递给它的直接子节点。它会引发儿童未定义的错误
我还将组件结构更新为
--Home ~ this is more like a welcome containing app's menu
--Wrapper
-gallery
-about
-links
这就是我所做的:我已经将Wrapper移动到画廊的包装,关于和链接
App.js
<Provider store={store} history={history}>
<BrowserRouter>
<div>
<Route exact path="/" component={Home}/>
<Route path="/h" component={Wrapper}/>
</div>
</BrowserRouter>
</Provider>
Wrapper.js
function mapStateToProps(state){
return{
gallery:state.gallery
}
}
function mapDispatchToProps(dispatch){
return bindActionCreators(actionCreators,dispatch)
}
class HomePage extends React.Component {
render() {
return(
<div>
<Route path={`${this.props.match.path}/portfolio`} component={ Gallery } />
<Route path={`${this.props.match.path}/about`} component={ About } />
<Route path={`${this.props.match.path}/links`} component={ Links } />
</div>
)
}
}
export default connect(
mapStateToProps,
mapDispatchToProps
)(Wrapper)
答案 0 :(得分:1)
您正确地将道具从Wrapper
传递给它的孩子。但是,Home
和Gallery
不是它的孩子。他们是伟大的大孩子。 Wrapper
的唯一子元素是其中的元素。在这种情况下,即BrowserRouter
。
您可以通过多种方式将这些道具提供给Home
和Gallery
。但直接从Wrapper
传递不是其中之一。
最简单的方法是制作GalleryContainer
课程。这与您已经创建的Wrapper
类相同(包括它与redux的连接),除了它将显式呈现Gallery
之外;
render() {
return <Gallery {...this.props}/>;
}
然后使用这个新的GalleryContainer
作为/portfolio
路线的组件。
答案 1 :(得分:1)
我终于设法将道具传递给子组件。
我为我的项目创建了两个容器,一个作为主容器,另一个作为子组件Gallery,About和Links的父级。
这是App.js
中的结构const mainRouter=(
<Wrapper>
<Provider store={store} history={history}>
<BrowserRouter>
<div>
<Route exact path="/" component={Home}/>
<Route path="/h" component={Container}/>
</div>
</BrowserRouter>
</Provider>
</Wrapper>
)
然后在Container
中,我将它连接到redux,并创建到其子子组件的路径,并使用render来渲染组件并将图库道具传递给Gallery
<Route path={`${this.props.match.path}/portfolio`} render={()=><Gallery {...this.props.gallery}/>}/>
这是容器
import React from 'react'
import { bindActionCreators } from 'redux'
import { connect } from 'react-redux'
import * as actionCreators from '../actions/actionCreators'
import { Route } from 'react-router-dom'
//import components
...
function mapStateToProps(state) {
return {
gallery: state.gallery
}
}
function mapDispatchToProps(dispatch) {
return bindActionCreators(actionCreators, dispatch)
}
class Container extends React.Component {
render() {
return (
<div>
<ResponsiveNav/>
<main>
<Route path={`${this.props.match.path}/portfolio`}
render={ ()=><Gallery{...this.props}/> } />
<Route path={`${this.props.match.path}/links`}
render={ ()=><Link{...this.props}/> } />
<Route path={`${this.props.match.path}/about`}
render={ ()=><About{...this.props}/> } />
</main>
<Footer/>
</div>
)
}
}
export default connect(
mapStateToProps,
mapDispatchToProps
)(Container)