React:新安装的子组件无法访问父组件引用?

时间:2015-12-29 00:59:39

标签: javascript scroll reactjs scrollbar

我在做什么:

简单 - 我需要在组件包含它(Messages)时立即滚动到消息列表的底部。

我的计划中的猴子扳手:)

安装后滚动到底部很好,直到......

我只是通过获取可滚动子组件headerMessages)并将其移动到其父组件(MessageSection)中来移动一些家具。为了让header坚持下去。

这是一个BEFORE和一个AFTER:

之前(是的,它的工作!) 的 MessageSection.js

if(this.state.messages !== null) 
  return (
    <ScrollArea speed={0.8} className="area" contentClassName="content">
      <Messages  messages={this.state.messages} />
    </ScrollArea>
  );
}else{

  return (
    <ScrollArea speed={0.8} className="area" contentClassName="content">
      <EmptyMessages />
    </ScrollArea>
  );
}

简单差异:

(基本上只是将Messages的标题移到了父MessageSection}

  1. 将标题从滚动的子组件(Messages)中拉出来。

  2. 将标题放在ScrollArea

  3. 上方
  4. 然后渲染新的JSX -I将Header和ScrollArea包装在一个新div中(&#34; messages&#34;)

  5. 之后:(什么!你不工作吗?)

    MessageSection.js

    if(this.state.messages !== null) {
      return (
        <div className="messages">
          <div className ="messages-section-header">
            <span className="header">{this.props.name}</span>
          </div>
          <ScrollArea speed={0.8} className="area scrollarea-flex" contentClassName="content">
            <Messages  messages={this.state.messages} />
          </ScrollArea>
        </div>
      );
    }else{
      return (
        <div className="messages">
          <ScrollArea speed={0.8} className="area scrollarea-flex" contentClassName="content">
            <EmptyMessages />
          </ScrollArea>
        </div>
      );
    }
    

    错误:

    重组后,我从ScrollArea.jsx#L222

    收到此错误

    未捕获的TypeError:无法读取属性&#39; offsetHeight&#39;

    错误原因:

    当可滚动组件Messages安装在其componentDidMount中时,它会尝试使用ScrollArea组件的公开上下文滚动到底部,但{ refs内的{1}}不存在。这很奇怪,因为如果ScrollArea稍后调用

    refs将会存在

    对于Reference,这里是发生故障的子组件。

    MessageList.js (在安装时尝试滚动到底部的可滚动组件)

    componentDidUpdate

    为什么我感到困惑:

    如何安装contextTypes: { scrollArea: React.PropTypes.object //Used by the Library to Access the Scrolling Panel(The Parent Component) }, componentDidMount: function() { this._scrollToBottom(); }, _scrollToBottom: function() { var scrollHeight = this.refs.messages.scrollHeight; this.context.scrollArea.scrollYTo(scrollHeight);//ERROR -the refs will not exist inside context as expected } 以及它的子ScrollArea也可以挂载并调用已定义的上下文Messages是没有意义的。暴露于它,但ScrollArea的参考不存在? 这是令人困惑的,因为它在我做了一点改变之前就已经有效了。

    问题:

    如何对代码结构进行简单更改会导致上下文无法访问它的参考

1 个答案:

答案 0 :(得分:2)

父组件未安装&#34;直到它的所有孩子都被安装后#34;所以你的ScrollArea仍处于&#34;安装&#34;当Message componentDidMount正在执行时。

您的问题是您对互动模式的结果:您有一个孩子&#34;组件指示某些父组件的行为。如果你让你的父组件负责这个滚动行为,那么一切都会有效。

具体来说,向componentDidMount组件添加MessageSection方法并将逻辑放在那里:

componentDidMount: function() {
    // Assume you add `ref="messages"` to your render method so you can
    // get a reference to the child component
    this.refs.messages._scrollToBottom();
}