【问题标题】:Reactjs: Accessing 'this' of a sibling componentReactjs:访问兄弟组件的“this”
【发布时间】:2016-08-21 17:26:34
【问题描述】:

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

<View><Content><Footer> 的父级。现在<Footer> 中有一个按钮,当它被点击时,我想在<Content> 组件中渲染一个Overlay,所以我必须能够访问我的@987654332 中<Content> 组件的this @ 零件。我不知道如何做到这一点。

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>

    )
  }

}

【问题讨论】:

  • “所以我必须在我的&lt;Footer&gt; 组件中访问this&lt;Content&gt; 组件。” 不,相反,Footer 应该接受一个回调到通知其“父级”(&lt;View&gt;)该按钮已被单击。然后&lt;View&gt; 可以更新其状态、重新渲染并将不同的道具或子代传递给&lt;Content&gt;,使其渲染覆盖层。

标签: javascript reactjs


【解决方案1】:

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

如果您想从Footer 访问Content 组件中的函数,您必须将该函数作为propFooter 提供给Footer

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

查看

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

【讨论】:

  • 是的,和你说的一样,我会发布一个答案来说明我是如何实现它的。无论如何,我会将您的答案标记为正确答案。
  • 很高兴它有帮助。 :)
【解决方案2】:

如果您使用 Redux 或 Flux,更好的方法是调度一些操作“DISPLAY_OVERLAY”。将一些 reducer 或存储值更改为 true,例如 reducer.displayOverlay=true;然后在 Content 组件的渲染方法中使用该 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 个子 显示消息和
    我有文本框和笑脸按钮。我需要当单击
    中的笑脸按钮时,在同一个聊天窗口的 组件中打开笑脸的叠加层,因此在此使用 store 会使其变得非常庞大,因为我必须为每个可以存储的聊天窗口存储状态尽可能多
【解决方案3】:

通过这样做,我可以在 &lt;Footer&gt; 组件中访问 &lt;Content&gt; 的“this”。现在我不确定我是否在道德上做错了事,伤害了 Reactjs 单向绑定的动机。我也在使用 redux,但是如何在 store 的帮助下解决这个问题。建议是非常可观的,因为我真的很困惑

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>

    )
  }

}

【讨论】:

  • 请更新您的原始问题,因为这不是答案。 :-)
  • 最后我可以在
    中访问 的“this”,这就是我的问题。如果你愿意,我可以通过添加所有这些代码使问题变得庞大。
猜你喜欢
  • 2017-06-13
  • 2018-10-08
  • 2019-05-17
  • 2019-04-06
  • 2019-11-11
  • 2019-09-17
  • 2017-11-11
  • 2019-04-16
  • 2017-08-12
相关资源
最近更新 更多