Reactjs:访问'这个'一个兄弟组件

时间:2016-04-27 12:09:53

标签: javascript reactjs

我的情况是我有3个组件; <View> <Content><Footer>

<View><Content><Footer>的父级。现在<Footer>中有一个按钮,当点击它时,我想在Overlay组件中呈现<Content>,因此我必须能够访问this的{​​{1}} <Content>组件中的<Footer>组件。我没有意识到如何实现这一点。

View.js

class View extends Component {
  render() {
    return (
      <div>
        <Content messages={this.props.messages}/>
        <Footer />
      </div>
    )
  }
}

Content.js

class Content extends Component {
  render() {
    return (
      <div>
        {this.props.messages}
      </div>
    )
  }

}

Footer.js

class Footer extends Component {
  constructor(props,context){
    super(props,context);
    this.state = {
      showEmojiPicker: false,
    }
  }

  handleToggleEmojiPicker() {
    this.setState({
      showEmojiPicker: !this.state.showEmojiPicker,
    });
  }

  render() {
    return (
      <div>
        <div>
          <div>
            <bootstrap.Button ref="targetEmojiPicker" bsSize="xsmall" onClick={this.handleToggleEmojiPicker.bind(this)}>
              <bootstrap.Glyphicon glyph="heart" />
            </bootstrap.Button>
              <bootstrap.Overlay
                  show={this.state.showEmojiPicker}
                  onHide={this.handleClose.bind(this)}
                  container={content.this}  //Need this of Content component
                  target={() => ReactDOM.findDOMNode(this.refs.targetEmojiPicker)}
              >
              <EmojiModalCategories actions={this.props.actions}/>
            </bootstrap.Overlay>
          </div>
        </div>
      </div>

    )
  }

}

3 个答案:

答案 0 :(得分:5)

您应该阅读官方React文档的Communicate between components页面。

如果您要访问Content Footer组件中的某个功能,则必须将该功能作为propFooter提供给View {1}}。

假设您要运行showOverlay()组件中的Content函数,您可以这样做:

视图

displayOverlay = () => {
  this.refs.content.showOverlay();
}

render() {
  //some code
  <Content ref="content" />
  //some code
  <Footer overlayButtonClick={this.displayOverlay} />
}

页脚

btnClick = () => {
  this.props.overlayButtonClick();
}    

render() {
  //some code
  <button onClick={this.btnClick}>Click</button>
  //some code
}

2017年8月编辑

请注意,现在不推荐使用ref值的字符串文字。有关详细信息,您可以查看我之前的回答here

答案 1 :(得分:1)

如果你正在使用Redux或Flux更好的方法,可以发送一些动作'DISPLAY_OVERLAY'。将某些reducer或store值更改为true,例如reducer.displayOverlay=true;然后在内容组件的渲染方法中使用该reducer值。

  render:function(){
    return <div>
    {reducer.displayOverLay? this.showOverlay():this.hideOverlay()}
    </div>
    } 

如果您不使用flux或redux,请使用您的视图组件状态。在视图组件状态中设置状态变量showOverlay:false。然后将showOverlay传递给Content组件

<Content showOverlay={this.state.showOverlay}/>

然后

查看

toggleOverLay(){
   this.setState({
       showOverlay:!this.state.showOverlay
    })
}
render() {
  //some code
  <Content showOverlay={this.state.showOverlay}/>
  //some code
  <Footer toggleOverlay={this.toggleOverlay} />
}

<强>页脚

 btnClick = () => {
  this.props.toggleOverlay();
}    

render() {
  //some code
  <button onClick={this.btnClick}>Click</button>
  //some code
}

答案 2 :(得分:0)

通过这样做,我可以访问<Content>组件中<Footer>的“this”。现在我不确定道德上我做错了什么,伤害了Reactjs单向约束的动机。我也在使用redux,但是如何在商店的帮助下解决这个问题。建议是非常值得的,因为我真的很混乱

View.js

class View extends Component {

  constructor(props,context){
    super(props,context);
    this.state = {
      thisOfContent: false    
    }
  }

  handleUpdateValue(newThisOfContent) {
    this.setState({
      thisOfContent: newThisOfContent
    })  
  }

  render() {
    return (
      <div>
        <Content handleUpdateValue={this.handleUpdateValue.bind(this)}/>
        <Footer stateValue={this.state.thisOfChatWindowContent}/>
      </div>
    )
  }

}

Content.js

class Content extends Component {

  componentDidMount() {
    this.props.handleUpdateValue(this);
  }

  render() {
    return (
      <div>

      </div>
    )
  }

}

Footer.js

class Footer extends Component {
  constructor(props,context){
    super(props,context);
    this.state = {
      showEmojiPicker: false,
    }
  }

  handleToggleEmojiPicker() {
    this.setState({
      showEmojiPicker: !this.state.showEmojiPicker,
    });
  }

  render() {
    return (
      <div>
        <div>
          <div>
            <bootstrap.Button ref="targetEmojiPicker" bsSize="xsmall" onClick={this.handleToggleEmojiPicker.bind(this)}>
              <bootstrap.Glyphicon glyph="heart" />
            </bootstrap.Button>
            <bootstrap.Overlay
                show={this.state.showEmojiPicker}
                onHide={this.handleClose.bind(this)}
                container={this.props.stateValue}
                target={() => ReactDOM.findDOMNode(this.refs.targetEmojiPicker)}
            >
              <EmojiModalCategories actions={this.props.actions}/>
            </bootstrap.Overlay>
          </div>
        </div>
      </div>

    )
  }

}