简体   繁体   English

React.js:访问同级组件的“ this”

[英]Reactjs: Accessing 'this' of a sibling component

I have a situation where I have 3 components; 我有3个组成部分的情况; <View> <Content> and <Footer> . <View> <Content><Footer>

<View> is parent of <Content> and <Footer> . <View><Content><Footer>父级。 Now there is a button in <Footer> and when it is clicked, I want to render an Overlay in the <Content> component, so i have to have access to this of the <Content> component inside my <Footer> component. 现在有一个按钮<Footer>并单击时,我想渲染的Overlay<Content>组件,所以我必须能够访问this了的<Content>我的内部组件<Footer>组件。 I am not getting on how to accomplish that. 我没有实现该目标。

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>

    )
  }

}

You should have a read at the Communicate between components page of the official React documentation. 您应该在官方的React文档的“ 在组件之间通信”页面上阅读。

If you want to access a function in the Content component from the Footer you'll have to supply that function as a prop to your Footer from the View . 如果要从Footer访问Content组件中的功能,则必须从View提供该功能作为对Footerprop

Assume you want to run the showOverlay() function that's in your Content component, you could do: 假设您要运行Content组件中的showOverlay()函数,可以执行以下操作:

View 视图

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

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

Footer 页脚

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

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

Edit August 2017 编辑2017年8月

Note that using string literals for ref value is now deprecated. 请注意,现在不建议使用字符串文字作为ref值。 For more info, you may have a look at an earlier answer I made, here . 有关更多信息,您可以在这里查看我之前的答案。

If you are using Redux Or Flux better approach would be dispatch some action 'DISPLAY_OVERLAY'. 如果您使用的是Redux或Flux,则最好分配一些操作“ DISPLAY_OVERLAY”。 change some reducer or store value to true for example reducer.displayOverlay=true ; 将一些reducer或store值更改为true,例如reducer.displayOverlay=true and then use that reducer value in your Content component's render method. 然后在Content组件的render方法中使用该reducer值。

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

if you are not using flux or redux then make use of your view component state. 如果您不使用flux或redux,请使用视图组件状态。 set a state variable showOverlay:false in your view components state. 在视图组件状态中设置状态变量showOverlay:false then pass that showOverlay down to Content component 然后将showOverlay传递给Content组件

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

then 然后

View 视图

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

Footer 页脚

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

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

By doing so I got access to 'this' of <Content> in <Footer> component. 这样,我就可以访问<Footer>组件中<Content> “ this”。 Now I am not sure if morally I am doing the wrong thing, hurting the Reactjs motive of one-way binding. 现在我不确定在道德上我是否做错了事,损害了单向绑定的Reactjs动机。 I'm using redux too, but how can I approach this with the help of store. 我也正在使用redux,但是如何在store的帮助下解决这个问题。 Suggestions are highly appreciable coz i'm literally confused 建议是非常可观的,因为我真的很困惑

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>

    )
  }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM