2016-11-02 21 views
0

私はFLuxまたはReduxを使用していないReactJSを使用しています。私は孫のコンポーネントが祖父母コンポーネントと通信(読み取り/更新)できるようにしたい。Reactjの親コンポーネントは子コンポーネントの子と通信します

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> 
    ); 
    } 
} 

子コンポーネントヘッダー

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; 
    } 
} 
ここ

は、App親コンポーネント です

OnTagBarコンポーネントが、関数を介してApp/Headerコンポーネントにデータを更新できるようにするにはどうしてもですか?setTabActive() onChange?

+0

あなたは、コンテキストを使用することができますが、それは練習をお勧めしません。 –

答えて

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>

関連する問題