首页 文章

Reactjs父组件与子组件的子进行通信

提问于
浏览
0

我正在使用没有FLux或Redux的ReactJS . 我希望grand child组件可以与他的祖父母组件进行通信(读取/更新数据) .

这是父组件 App

export default class App extends React.Component {
 static propTypes = {
   children: React.PropTypes.object.isRequired
 };

  constructor(props) {
    super(props);
    this.state = {
      tabActive: 0,
    };
  }
  setTabActive(item) {
    this.setState({
      tabActive: item,
    });
  }
  render() {
    return (
      <div>
        <Header tabActive={this.state.tabActive} />
        <Content>
          {this.props.children}
        </ Content>
        <Footer />
      </div>
    );
  }
}

子组件 Header

export default class Header extends React.Component {
  render() {
    return (
      <div>
          ....
         <SettingTabBar tabActive={this.props.tabActive} />
      </div>
    );
  }
}

儿童成分的孩子 SettingTabBar

export default class SettingTabBar extends React.Component {
  constructor(props) {
    super(props);
    this.state = { activeTab: this.props.tabActive  };
  }

  render() {
    if (location.pathname.indexOf('setting') > 0) {
      return (
        <Tabs activeTab={this.state.activeTab} onChange={tabId => this.setState({ activeTab: tabId })} ripple>
          <Tab>SETTING</Tab>
          <Tab>CHARTS</Tab>
          <Tab>HELP</Tab>
        </Tabs>
      );
    }
    return null;
  }
}

无论如何,当onChange时,SettingTabBar组件可以通过函数 setTabActive() 将数据更新到App / Header组件?

1 回答

  • 1

    对于与祖父母和孙子女的交流,您可以使用上下文 . 它没有被推荐,但它正在发挥作用 .

    // root component
    class App extends React.Component {
        constructor(props){
            super(props);
            this.state = {
                activeMenu: "none"
            };
        }
    
        getChildContext() {
            return {
                rootCallback: menuName => {
                    this.setState({activeMenu: menuName});
                }
            }
        }
    
        render() {
            return (
              <div>
                <div>Current active menu is: <strong>{this.state.activeMenu}</strong></div>
                <Child />
              </div>
            );
        }
    }
    
    // declare childContextTypes at context provider
    App.childContextTypes = {
        rootCallback: React.PropTypes.function
    }
    
    // intermediate child
    class Child extends React.Component {
        render() {
            return (
                <div>
                    <GrandChild />
                </div>
            );
        }
    }
    
    // grand child
    class GrandChild extends React.Component {
        render() {
            return ( 
                <div>
                    {/* get context by using this.context */}
                    <button 
                        type="button" 
                        onClick={()=>this.context.rootCallback("one")}
                    >
                        Activate menu one
                    </button>
                    <button 
                        type="button" 
                        onClick={()=>this.context.rootCallback("two")}
                    >
                        Activate menu two
                    </button>
                    <button 
                        type="button" 
                        onClick={()=>this.context.rootCallback("three")}
                    >
                        Activate menu three
                    </button>
                </div>
            )
        }
    }
    
    // also declare contextTypes at context consumer
    GrandChild.contextTypes = {
         rootCallback: React.PropTypes.function
    }
    
    // render it to DOM
    ReactDOM.render(<App /> , document.getElementById('app-mount'));
    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
    
    <div id="app-mount"></div>
    

相关问题