在 window.scroll 上获取 redux 状态
Get redux state on window.scroll
我想实现分页。因此,当用户向下滚动到底部时,我想进行 api 调用。我通过 window.scroll 看到我可以找到滚动的位置并且可以实现。但是我想访问 redux state 来获取 certian 数据。由于此事件未被任何组件绑定,因此我将无法传递数据。在这种情况下,正确的方法是什么?
如果我想通过一个简单的函数访问 redux store,我该怎么做?在滚动时,我如何确保只有请求通过?
您可以 执行滚动的组件。或者您可以将道具传递给具有商店信息的组件。这是到达您商店的两种推荐方式。也就是说你也可以看看上下文
class MyComponent extends React.Component {
someMethod() {
doSomethingWith(this.context.store);
}
render() {
...
}
}
MyComponent.contextTypes = {
store: React.PropTypes.object.isRequired
};
注意:上下文是可选的;您必须在组件上指定 contextTypes
才能获取它。
继续阅读 React's Context doc 它可能不是一个完整的解决方案,因为它可能会在未来的版本中被弃用
编辑:
根据您提供的清晰评论,您可以这样做。
import React, { Component } from 'react';
import ReactDOM = from 'react-dom';
import _ from 'lodash';
const defaultOffset = 300;
var topOfElement = function(element) {
if (!element) {
return 0;
}
return element.offsetTop + topOfElement(element.offsetParent);
};
class InfiniteScroll extends Component {
constructor(props) {
super(props);
this.listener = _.throttle(this.scrollListener, 200).bind(this);
}
componentDidMount() {
this.attachScrollListener();
}
componentWillUnmount() {
this.detachScrollListener();
}
scrollListener () {
var el = ReactDOM.findDOMNode(this);
var offset = this.props.offset || defaultOffset;
var scrollTop = (window.pageYOffset !== undefined) ? window.pageYOffset : (document.documentElement || document.body.parentNode || document.body).scrollTop;
if (topOfElement(el) + el.offsetHeight - scrollTop - window.innerHeight < offset) {
this.props.somethingHere;
}
}
attachScrollListener() {
window.addEventListener('scroll', this.listener);
window.addEventListener('resize', this.listener);
this.listener();
}
detachScrollListener() {
window.removeEventListener('scroll', this.listener);
window.removeEventListener('resize', this.listener);
}
render() {
return (...)
}
}
export default connect(mapStateToProps, mapDispatchToProps)(InfiniteScroll);
我在此处的导入中添加了 lodash,这样您就可以限制滚动侦听器功能。你只想每秒调用处理函数那么多次,否则它会开始滞后于页面(取决于监听函数的重量)
在组件中访问应用程序状态的正确方法是使用 react-redux
和选择器函数。
react-redux
提供了一个名为 connect
的函数。您应该使用此函数来定义要将我们状态中的哪些值映射到组件的道具,以便这些值可用。
此映射所需的函数称为 mapStateToProps
,其中 returns 具有应传递给组件的值的对象。
您还可以定义应该在组件中可用的 redux 操作(例如,用于触发下一页的加载)。该函数称为 mapDispatchToProps
.
举个例子:
import React from 'react';
import { connect } from 'react-redux';
import { getUsersPage } from './selectors';
import { loadUsersPage } from './actions';
class MyComponent extends React.Component {
handleScroll () {
this.props.loadUsersPage({ page: lastPage + 1 });
}
render () {
const users = this.props.users;
// ...
}
}
const mapStateToThis = (state) => {
return {
users: getUsers(state)
};
}
const mapDispatchToProps = (dispatch) => {
return {
loadUsersPage: (payload) => {
dispatch (loadUsersPage(payload));
}
}
};
export default connect()(MyComponent);
我想实现分页。因此,当用户向下滚动到底部时,我想进行 api 调用。我通过 window.scroll 看到我可以找到滚动的位置并且可以实现。但是我想访问 redux state 来获取 certian 数据。由于此事件未被任何组件绑定,因此我将无法传递数据。在这种情况下,正确的方法是什么? 如果我想通过一个简单的函数访问 redux store,我该怎么做?在滚动时,我如何确保只有请求通过?
您可以
class MyComponent extends React.Component {
someMethod() {
doSomethingWith(this.context.store);
}
render() {
...
}
}
MyComponent.contextTypes = {
store: React.PropTypes.object.isRequired
};
注意:上下文是可选的;您必须在组件上指定 contextTypes
才能获取它。
继续阅读 React's Context doc 它可能不是一个完整的解决方案,因为它可能会在未来的版本中被弃用
编辑:
根据您提供的清晰评论,您可以这样做。
import React, { Component } from 'react';
import ReactDOM = from 'react-dom';
import _ from 'lodash';
const defaultOffset = 300;
var topOfElement = function(element) {
if (!element) {
return 0;
}
return element.offsetTop + topOfElement(element.offsetParent);
};
class InfiniteScroll extends Component {
constructor(props) {
super(props);
this.listener = _.throttle(this.scrollListener, 200).bind(this);
}
componentDidMount() {
this.attachScrollListener();
}
componentWillUnmount() {
this.detachScrollListener();
}
scrollListener () {
var el = ReactDOM.findDOMNode(this);
var offset = this.props.offset || defaultOffset;
var scrollTop = (window.pageYOffset !== undefined) ? window.pageYOffset : (document.documentElement || document.body.parentNode || document.body).scrollTop;
if (topOfElement(el) + el.offsetHeight - scrollTop - window.innerHeight < offset) {
this.props.somethingHere;
}
}
attachScrollListener() {
window.addEventListener('scroll', this.listener);
window.addEventListener('resize', this.listener);
this.listener();
}
detachScrollListener() {
window.removeEventListener('scroll', this.listener);
window.removeEventListener('resize', this.listener);
}
render() {
return (...)
}
}
export default connect(mapStateToProps, mapDispatchToProps)(InfiniteScroll);
我在此处的导入中添加了 lodash,这样您就可以限制滚动侦听器功能。你只想每秒调用处理函数那么多次,否则它会开始滞后于页面(取决于监听函数的重量)
在组件中访问应用程序状态的正确方法是使用 react-redux
和选择器函数。
react-redux
提供了一个名为 connect
的函数。您应该使用此函数来定义要将我们状态中的哪些值映射到组件的道具,以便这些值可用。
此映射所需的函数称为 mapStateToProps
,其中 returns 具有应传递给组件的值的对象。
您还可以定义应该在组件中可用的 redux 操作(例如,用于触发下一页的加载)。该函数称为 mapDispatchToProps
.
举个例子:
import React from 'react';
import { connect } from 'react-redux';
import { getUsersPage } from './selectors';
import { loadUsersPage } from './actions';
class MyComponent extends React.Component {
handleScroll () {
this.props.loadUsersPage({ page: lastPage + 1 });
}
render () {
const users = this.props.users;
// ...
}
}
const mapStateToThis = (state) => {
return {
users: getUsers(state)
};
}
const mapDispatchToProps = (dispatch) => {
return {
loadUsersPage: (payload) => {
dispatch (loadUsersPage(payload));
}
}
};
export default connect()(MyComponent);