从App组件更改子元素的状态

时间:2016-02-29 10:15:44

标签: javascript reactjs

我目前的应用程序组件设置如下:

var App = React.createClass({
  test: function() {
    return null
  },
  render: function() {
    return (
      <div>
        <Navbar>
          <NavButton text="Test Button" onClick={this.test} />
        </Navbar>
        <PopupMenu />
        <Map />
      </div>
    );
  }
});

正如您在导航按钮上看到的,我有一个点击事件设置,但是当它被点击时,我希望它通过将PopupMenu的state.visible更改为true来显示PopupMenu组件。但是,我不想硬编码&#39;这在导航按钮中,因为不同的按钮应该能够触发不同的事件。

另一方面,当出现该菜单时,如何在该菜单中有一个按钮调用Map组件上的一个函数?为了给它一些上下文,按钮会将geojson传递给地图或在地图上触发ajax调用以返回geojso,以便它可以映射数据。

如果这没有任何意义,请问我,我会进一步解释。

谢谢!

2 个答案:

答案 0 :(得分:1)

您可以使用refs

var PopupMenu = React.createClass({
    [...]
    show: function () { [...] } 
    [...]
});

var App = React.createClass({
  test: function() {
    this.refs['popop'].show();
  },
  render: function() {
    return (
      <div>
        <Navbar>
          <NavButton text="Test Button" onClick={this.test} />
        </Navbar>
        <PopupMenu ref="popup" />
        <Map />
      </div>
    );
  }
});

答案 1 :(得分:0)

如果您不想使用ECMA-6,请重新考虑代码或使用转发器

import React,{Component} from 'react';
import ReactDOM from 'react-dom'; //npm install react-dom --save
import update from 'react-addons-update' //npm install react-addons-update --save
//import other required stuff


class App extends Component{

  constructor() {
    super(...arguments);
    //set the initial state of componenet
    this.state={
    show:false,
    mapData: {}
  }
}

  test(){
    //toggle visibility
    let newState= update( this.state.show,{$set:!this.state.show});

    this.setState(
      {
        show:newState,
        mapData:this.state.mapData
    });
  }

  getSetMapData(){
   //...fetch data for map
   // and alter the state
   let newState= update(this.state.mapData,{$set:fetched_data});
   this.setState(
     {
        show:this.state.show,
        mapData:newState
     });
  }

  render() {

    if(this.state.show){
      //don't use [let] here 
      var pM=(<PopupMenu mapDataFetch={this.getSetMapData.bind(this)} />) ;
    }

    return (
      <div>
        <Navbar>
          <NavButton text="Test Button" onClick={this.test.bind(this)} />
        </Navbar>
        {pM} //change here
        <Map mapData={this.state.mapData}/>
      </div>
    );
  }
}
ReactDOM.render(<App />,document.getElementById('elem'));

您过多地填充单个组件,尝试分解您的组件。例如,您可以将NavButton作为Navbar组件的子项移动到其渲染函数中。

最好让最外面的组件为state-full,并通过层次结构Parent(state-full)->Children(also Parent)->Children...之后的属性将状态作为输入传递给子节点。例如,App&#39; getSetMapData函数作为其属性传递给PopupMenu

//and further in render function of `PopupMenu` you can pass 
//it to button nested in `PopupMenu` 

<button onClick={this.props.mapDataFetch}>Map's Data</button>