2017-02-22 18 views
1

我想实现分页。所以,当用户滚动到底部时,我想进行api调用。我通过window.scroll看到我可以找到滚动的位置,并可以实现这一点。但是我想访问redux状态来获取certian数据。由于此事件不受任何组件绑定,因此我将无法传递数据。在这种情况下,正确的做法是什么? 如果我想通过一个简单的函数访问redux商店我该怎么做?并在滚动如何确保只有请求通过?在window.scroll上获取redux状态

+0

我还没有使用它,但也许[反应 - 无限滚动](https://github.com/CassetteRocks/react-infinite-scroller)可以帮助你。 –

+0

@JoPeyper谢谢。我发现https://github.com/brigade/react-waypoint看起来很有趣。 – scripter

回答

3

您可以connect做滚动的组件。或者您可以将道具传递给具有商店信息的组件。这是推荐您的商店的两种方式。这就是说你也可以看看背景

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,因此您可以调节滚动侦听器功能。您只希望每秒钟调用处理函数几次,或者可以启动滞后页面(取决于监听函数的重量)

+0

你可以连接你的滚动组件吗?那个组件会是什么? ,因为我想调用window.scroll。我不想要一个固定的容器来滚动。我想要像Facebook一样的东西,当你向下滚动时得到新的数据 – scripter

+0

@scripter我假设你将创建一个'InfiniteScroll'组件来处理'window.scroll'监听器和一切,这样你就可以在多个代码中使用一个地方。我在说这个组件(或者如果你没有创建一个无限的滚动组件,那么应该请求更多数据的组件)就可以连接起来。 –

+1

如果没有必要,您不应直接通过商店使用redux商店。在这种情况下,您应该使用官方模块来连接组件和redux商店:'react-redux'; – floriangosse

0

在组件中访问应用程序状态的正确方法是使用react-redux和选择器功能。

react-redux提供了称为connect的功能。您应该使用此函数来定义您想要映射到组件的道具的状态中的哪些值,以便这些值可用。

您需要用于此映射的函数称为mapStateToProps,它返回一个对象,其中应传递给该组件的值。

此外,您还可以定义应该在组件中使用的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);