Aar*_*ken 6 javascript dom reactjs react-dom
我知道这不是惯用的React,但我正在研究一个React组件(反向滚动视图),它需要在渲染之前和渲染之后获得下游虚拟DOM更改的通知.
这有点难以解释所以我创建了一个JSFiddle起点:https://jsfiddle.net/7hwtxdap/2/
我的目标是让日志看起来像:
Begin log
render
rendered small
rendered small
rendered small
before update
rendered big
after update
before update
rendered big
after update
before update
rendered big
after update
Run Code Online (Sandbox Code Playgroud)
我知道React有时批处理DOM更改,这很好(即日志事件可能before update; rendered big; rendered big; after update; ...) - 重要的是我在DOM更改之前和之后实际通知了.
我可以通过指定回调来手动近似行为,如下所示:https://jsfiddle.net/7hwtxdap/4/.然而,这种方法并不具有规模 - 例如,我需要让后代而不是儿童发生事件; 而且不想在我使用的每个组件上添加这些事件处理程序.
使用案例:
我正在为消息制作一个"反向滚动组件"(其中,当添加新元素或现有元素改变大小时,滚动更改的基础是从内容的底部而不是每个消息传递应用程序的顶部ala)动态修改了子节点(类似于<MyElement />类但具有可变高度,来自ajax的数据等).这些不是从类似Flux的状态存储中获取数据,而是使用pub-sub数据同步模型(与setTimeout()非常接近).
要使反向滚动工作,您需要执行以下操作:
anyChildrenOfComponentWillUpdate() {
let m = this.refs.x;
this.scrollBottom = m.scrollHeight - m.scrollTop - m.offsetHeight;
}
anyChildrenOfComponentDidUpdate() {
let m = this.refs.x;
m.scrollTop = m.scrollHeight - m.offsetHeight - this.scrollBottom;
}
Run Code Online (Sandbox Code Playgroud)
重要的是,对于这种设计,我希望能够将元素包装在不是"反向滚动感知"的其他元素周围(即,不必具有特殊代码来通知反向滚动处理程序它们已经改变).
如果不知道为什么需要此功能,就很难知道解决问题的最佳解决方案是什么。不过,我将解决这个具体问题:
例如,我需要让事件从后代而不是孩子中冒出来;并且不想将此类事件处理程序添加到我使用的每个组件中。
我建议对此解决方案进行两处更改。第一个是考虑使用context,但在决定这样做之前请务必阅读警告。这将允许您在单个组件中定义回调,并让它们立即在所有后代中可用。
第二个更改是将所有日志记录逻辑移至单独的组件中,并让其他组件根据需要继承它。该组件看起来像:
class LoggingComponent extends React.Component {
componentWillUpdate() {
if (this.context.onWillUpdate) {
this.context.onWillUpdate();
}
}
componentDidUpdate() {
if (this.context.onDidUpdate) {
this.context.onDidUpdate();
}
}
}
LoggingComponent.contextTypes = {
onWillUpdate: React.PropTypes.func,
onDidUpdate: React.PropTypes.func
};
Run Code Online (Sandbox Code Playgroud)
这样,您可以轻松地将此功能添加到新组件中,而无需重复逻辑。我已经用一个工作演示更新了你的jsfiddle 。
| 归档时间: |
|
| 查看次数: |
932 次 |
| 最近记录: |