React.js关于从组件中侦听窗口事件的最佳实践 [英] React.js best practice regarding listening to window events from components
问题描述
我根据它们在视口中的位置设置了几个React.js组件的动画。如果组件位于视口中,则将不透明度设置为1,如果它不在视口中,则将其不透明度设置为0.我使用 getBoundingClient()
的 top
和 bottom
属性,用于确定组件是否在视口中。
I am animating several React.js components based on their position in the viewport. If the component is in the viewport, animate the opacity to 1, if it's not in the viewport, animate its opacity to 0. I am using getBoundingClient()
's top
and bottom
properties to determine if the component is within the viewport.
ComponentA显示了其他B,C和D组件所遵循的模式。他们每个人都在监听窗口
滚动事件。
ComponentA shows the pattern I followed for the other B, C, and D components. They each are listening for the window
scroll event.
这是React方法,每个组件必须向窗口添加一个事件监听器
?同一窗口上有多个滚动事件侦听器?
Is this the "React" way to do this by each component having its having to add an event listener to the window
? Multiple scroll event listeners on the same window?
或者,在 Home
所有者组件中,将滚动事件监听器添加到窗口是否有更好的方法?那么ownee子组件是否仍然能够使用 getBoundingClient()
知道它们在DOM中的位置?
Or is there a better way by adding the scroll event listener to the window once at the Home
owner component? Then would the ownee child components still be able to know where they are in the DOM using the getBoundingClient()
?
Home = React.createClass({
render: function() {
<div>
<ComponentA />
<ComponentB />
<ComponentC />
<ComponentD />
</div>
};
});
ComponentA = React.createClass({
componentDidMount: function() {
window.addEventListener('scroll', this.handleScroll);
},
componentWillUnmount: function() {
window.removeEventListener('scroll', this.handleScroll);
},
handleScroll: function() {
var domElement = this.refs.domElement.getDOMNode();
this.inViewPort(domElement);
},
inViewPort: function(element) {
var elementBounds = element.getBoundingClientRect();
(elementBounds.top <= 769 && elementBounds.bottom >= 430) ? TweenMax.to(element, 1.5, { opacity: 1 }) : TweenMax.to(element, 1.5, { opacity: 0 });
},
render: function() {
return (/* html to render */);
}
});
推荐答案
有几种不同的方法可以做到这一点。一个是通过组合:
There are a few different ways you could do this. One is through composition:
var React = require("react");
var _ = require("underscore");
var ScrollWrapper = React.createClass({
propTypes: {
onWindowScroll: React.PropTypes.func
},
handleScroll: function(event) {
// Do something generic, if you have to
console.log("ScrollWrapper's handleScroll");
// Call the passed-in prop
if (this.props.onWindowScroll) this.props.onWindowScroll(event);
},
render: function () {
return this.props.children;
},
componentDidMount: function() {
if (this.props.onWindowScroll) window.addEventListener("scroll", this.handleScroll);
},
componentWillUnmount: function() {
if (this.props.onWindowScroll) window.removeEventListener("scroll", this.handleScroll);
}
});
var ComponentA = React.createClass({
handleScroll: function(event) {
console.log("ComponentA's handleScroll");
},
render: function() {
return (
<ScrollWrapper onWindowScroll={this.handleScroll}>
<div>whatever</div>
</ScrollWrapper>
);
}
});
现在,您可以将通用逻辑放在 ScrollWrapper $ c中$ c>组件,突然变得可重用。你可以创建一个
ComponentB
来呈现 ScrollWrapper
就像 ComponentA
的确如此。
Now, you can place your generic logic in the ScrollWrapper
component, and suddenly it becomes reusable. You could create a ComponentB
that renders a ScrollWrapper
just like ComponentA
does.
为了满足你的例子,也许你必须从<$ c $传递 ScrollWrapper
一些额外的道具C> ComponentA 。也许你会传递一个包含 ref
实例的道具来调用你的逻辑。您甚至可以传递一些选项或参数来自定义补间或边界。我没有编写任何代码,因为我认为你会理解它,并且能够使用我提供的基础为你自己定制/编写它。
To satisfy your example, maybe you'll have to pass the ScrollWrapper
some extra props from ComponentA
. Maybe you'll pass it a prop that contains an instance of the ref
to call your logic on. You could even pass it some options or arguments to customize the tween or the bounds. I didn't code any of this because I think you'll understand it and be able to customize/write it for yourself with the base I've provided.
其他实现此类事情的方法是通过Mixin。尽管如此,有很多关于Mixins是好还是坏的讨论,他们甚至可能在未来被React弃用?你可以阅读一下这个,然后自己决定你的想法。
The other way to achieve this sort of thing is through a Mixin. Although, there's a lot of talk about if Mixins are good or bad, and they might even be being deprecated by React in the future? You can do some reading about this and decide for yourself what you think.
这篇关于React.js关于从组件中侦听窗口事件的最佳实践的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!