作为路径prop传递时,状态值不更新

时间:2016-11-22 14:38:11

标签: javascript reactjs react-router

我遇到了react-router版本3的问题,我将路由状态作为道具传递,以及更新父状态值的点击处理程序。

虽然在主页组件中点击后,父 sidebarOpen 状态值会发生变化,但 sidebarState 值仍保留在初始值 false

当路由器类中的状态发生变化时,有没有办法确保将更新的状态值传递给接收组件?

首先点击:
sidebarOpen:假
sidebarState:false

第二次点击:
sidebarOpen:真
sidebarState:false

第三次点击:
sidebarOpen:假
sidebarState:false

var Home = React.createClass({
  handleViewSidebar: function(){  
    this.props.route.clickHandler();
    console.log('sidebarState:' + this.props.route.sidebarState);
  },
  render: function() {
    return (
       <div>
         <Header onClick={ this.handleViewSidebar } />
         <SideBar isOpen={ this.props.route.sidebarState } onClick={ this.handleViewSidebar } />
         <Content isOpen={ this.props.route.sidebarState } />
       </div>
    );
  }
});



var App = React.createClass({
  getInitialState: function(){
    return {sidebarOpen: false};
  },
  handleViewSidebar: function(){
    this.setState({sidebarOpen: !this.state.sidebarOpen});
    console.log('sidebarOpen:' + this.state.sidebarOpen);
  },
  render: function() {
    return (
      <Router history={ hashHistory }>
        <Route path="/"         
          sidebarState={ this.state.sidebarOpen } 
          clickHandler={ this.handleViewSidebar } 
          component={ Home }>Home</Route>
        <Route path="/about"    
          sidebarState={ this.state.sidebarOpen } 
          clickHandler={ this.handleViewSidebar } 
          component={ About }>About</Route>
        <Route path="/contact"  
          sidebarState={ this.state.sidebarOpen } 
          clickHandler={ this.handleViewSidebar } 
          component={ Contact }>Contact</Route>
      </Router>
    );
  }
});


ReactDOM.render(<App />, document.getElementById('app'));

1 个答案:

答案 0 :(得分:4)

我的建议是重构您的组件,以便您拥有:

  • 仅处理路由的根组件

  • 一个App组件,它将包含其他路由的组件以及句柄侧栏逻辑和状态

  • 您的其他组件(Home,About,Contact)将是App的子路由,因此可以通过props继承状态和处理程序。

然后,您可以React.Children.map超过this.props.chidren属性(当您在其他路由中嵌套路由时,由React-Router提供给App),然后使用React.cloneElement创建子项并分配它们状态和处理程序通过道具。

所以你的代码看起来像这样:

var Routes = React.createClass({
  render: function() {
    return (
      <Router history={ hashHistory }>
        <Route path="/" component={App}>
          <IndexRoute component={ Home }>Home</Route>
          <Route path="/about" component={ About }>About</Route>
          <Route path="/contact" component={ Contact }>Contact</Route>
        </Route>
      </Router>
    );
  }
});

var App = React.createClass({
  getInitialState: function(){
    return {sidebarOpen: false};
  },
  handleViewSidebar: function(){  
    this.setState({sidebarOpen: !this.state.sidebarOpen});
  },
  render: function() {
    const childWithProps = 
      React.Children.map(
        this.props.children, 
          child => {
            return (
              React.cloneElement(child, {
                sidebarOpen : this.state.sidebarOpen,
                handleViewSidebar: this.handleViewSidebar
              }
            )
          }
      )
    return (
       <div>
         {childWithProps}
       </div>
    );
  }
});





ReactDOM.render(<App />, document.getElementById('app'));