我根据它们在视口中的位置设置了几个React.js组件的动画。如果组件位于视口中,则将不透明度设置为1,如果它不在视口中,则将其不透明度设置为0.我使用getBoundingClient()
的{{1}}和top
属性确定组件是否在视口中。
ComponentA显示了其他B,C和D组件所遵循的模式。他们每个人都在监听bottom
滚动事件。
这是“React”方法,每个组件必须向window
添加一个事件监听器吗?同一窗口上有多个滚动事件侦听器?
或者,通过在window
所有者组件中将滚动事件侦听器添加到窗口,有没有更好的方法?那么ownee子组件是否仍然能够使用Home
知道它们在DOM中的位置?
getBoundingClient()
答案 0 :(得分:32)
有几种不同的方法可以做到这一点。一个是通过作文:
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
组件中,然后突然变得可重用。您可以创建一个ComponentB
,就像ScrollWrapper
一样呈现ComponentA
。
为了满足你的榜样,也许你必须从ScrollWrapper
传递ComponentA
一些额外的道具。也许你会传给它一个包含ref
实例的道具来调用你的逻辑。您甚至可以传递一些选项或参数来自定义补间或边界。我没有编写任何代码,因为我认为你会理解它,并且能够使用我提供的基础为你自己定制/编写它。
实现此类目标的另一种方法是通过Mixin。虽然,有很多关于Mixins是好还是坏的讨论,他们甚至可能在未来被React弃用?你可以阅读一下这个,然后自己决定你的想法。
答案 1 :(得分:16)
这是一个更简单的代码段,可以根据需要运行。您缺少this
绑定,因此,当您执行window.addEventListener('scroll', this.handleScroll);
时,您实际上将this
指向窗口对象。
相反,您需要在构造函数中绑定它。希望它
class Home extends Component {
constructor(props) {
super(props)
this.handleScroll = this.handleScroll.bind(this);
}
componentDidMount() {
window.addEventListener('scroll', this.handleScroll);
}
componentWillUnmount() {
window.removeEventListener('scroll', this.handleScroll);
}
handleScroll(e) {
console.log('scroll event');
console.log(e);
}
render() {
return (
<div>
<ComponentA />
<ComponentB />
<ComponentC />
<ComponentD />
</div>
);
}
}
另一个选项如下,两个选项都应该有效:)
class Home extends Component {
componentDidMount() {
window.addEventListener('scroll', this.handleScroll.bind(this));
}
componentWillUnmount() {
window.removeEventListener('scroll', this.handleScroll.bind(this));
}
handleScroll(e) {
console.log('scroll event');
console.log(e);
}
render() {
return (
<div>
<ComponentA />
<ComponentB />
<ComponentC />
<ComponentD />
</div>
);
}
}
答案 2 :(得分:11)
这里是带有useEffect挂钩的实用样式:
$role = DB::table('role_user')->select('role_id')->where('company_id', $cp)->get();
foreach ($role as $key) {
$role = $key;
}
$roles = Role::where('id', $role->role_id)->get();
答案 3 :(得分:2)
我肯定会添加一个事件监听器/组件。意识形态是将具有可重复使用的分离组件放置在应用程序中的“任何位置” - 以最大限度地减少代码冗余。
因此,您按照合作伙伴保留事件列表的方法是有效的。