无法将根组件道具传递给子组件

时间:2017-09-18 21:21:32

标签: reactjs redux react-router-v4

我在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)

2 个答案:

答案 0 :(得分:1)

您正确地将道具从Wrapper传递给它的孩子。但是,HomeGallery不是它的孩子。他们是伟大的大孩子。 Wrapper的唯一子元素是其中的元素。在这种情况下,即BrowserRouter

您可以通过多种方式将这些道具提供给HomeGallery。但直接从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)