反应:新安装的 child 组件无法访问 Parent 组件引用?
React: Parent component refs not accessible to newly mounted child component?
我在做什么:
简单 - 我需要在安装包含消息列表的组件 (Messages
) 后立即滚动到消息列表的底部。
我程序中的活动扳手:)
安装后滚动到底部没问题,直到...
我简单地移动了一些家具,将 scroll-able child 组件(Messages
)的 header
移到了它的 parent 中component(MessageSection
) 为了让 header
坚持。
这是之前和之后:
之前(太棒了!)
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
的标题移动到parent MessageSection
)
从滚动 child 组件中拉出 header(Messages
)。
将header放在ScrollArea上方
然后渲染新的 JSX -我将 Header 和 ScrollArea 包裹在一个新的 div ("messages")
之后:(什么!你不工作了??)
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
得到了这个错误
未捕获类型错误:无法读取 属性 'offsetHeight'
错误原因:
当 scroll-able 组件 Messages
安装在它的 componentDidMount
中时,它会尝试使用 ScrollArea
组件的公开上下文滚动到底部,但是refs
里面的ScrollArea
是不存在的。这很奇怪,因为如果稍后由 componentDidUpdate
调用,refs
将存在
作为参考,这里是发生故障的 child 组件。
MessageList.js(Scroll-able 安装时尝试滚动到底部的组件)
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
怎么挂载,childMessages
也可以挂载,调用定义的上下文ScrollArea
暴露给它,但 ScrollArea
的引用不存在???
这是双重混乱,因为它在我做小改动之前就起作用了。
问题:
我的代码结构中的简单更改怎么会导致上下文无法访问它的引用
父组件只有在其所有子组件 "mounted" 之后才 "mounted"。所以当你的 Message
componentDidMount
正在执行时,你的 ScrollArea
仍在 "mounting" 的过程中。
您的问题是您为交互建模的方式造成的:您有一个 "child" 组件指示某些父组件的行为。如果你让你的父组件负责这个滚动行为,那么一切都会起作用。
具体来说,将 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();
}
我在做什么:
简单 - 我需要在安装包含消息列表的组件 (Messages
) 后立即滚动到消息列表的底部。
我程序中的活动扳手:)
安装后滚动到底部没问题,直到...
我简单地移动了一些家具,将 scroll-able child 组件(Messages
)的 header
移到了它的 parent 中component(MessageSection
) 为了让 header
坚持。
这是之前和之后:
之前(太棒了!) 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
的标题移动到parent MessageSection
)
从滚动 child 组件中拉出 header(
Messages
)。将header放在ScrollArea上方
然后渲染新的 JSX -我将 Header 和 ScrollArea 包裹在一个新的 div ("messages")
之后:(什么!你不工作了??)
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
得到了这个错误未捕获类型错误:无法读取 属性 'offsetHeight'
错误原因:
当 scroll-able 组件 Messages
安装在它的 componentDidMount
中时,它会尝试使用 ScrollArea
组件的公开上下文滚动到底部,但是refs
里面的ScrollArea
是不存在的。这很奇怪,因为如果稍后由 componentDidUpdate
refs
将存在
作为参考,这里是发生故障的 child 组件。
MessageList.js(Scroll-able 安装时尝试滚动到底部的组件)
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
怎么挂载,childMessages
也可以挂载,调用定义的上下文ScrollArea
暴露给它,但 ScrollArea
的引用不存在???
这是双重混乱,因为它在我做小改动之前就起作用了。
问题:
我的代码结构中的简单更改怎么会导致上下文无法访问它的引用
父组件只有在其所有子组件 "mounted" 之后才 "mounted"。所以当你的 Message
componentDidMount
正在执行时,你的 ScrollArea
仍在 "mounting" 的过程中。
您的问题是您为交互建模的方式造成的:您有一个 "child" 组件指示某些父组件的行为。如果你让你的父组件负责这个滚动行为,那么一切都会起作用。
具体来说,将 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();
}