Renato Cassino
Renato Cassino

Reputation: 840

Append to infinite scroll in reactJs

I'm making a infinite scroll in ReactJs with posts.

I have a react class called AllPosts and Post. AllPosts render multiple Posts.

I have this code:

ReactDOM.render(
    <AllPosts data={posts} />,
    document.querySelector(render_to)
);

And below is the method

// Render all posts
var AllPosts = React.createClass({

    render: function () {
        return (
            <div>
                {this.props.data.map(function(element, i) {
                    return <Post data={element} />
                })}
            </div>
        ); .....

But, I have an event in scroll and I want to append another react Post. How can I do this?

Upvotes: 2

Views: 2630

Answers (1)

Joshua Comeau
Joshua Comeau

Reputation: 2753

This is one of those awesome things React is great at :)

On the assumption that you don't want to use a Flux/Redux implementation, I would set the posts data as the state on your root component. That way, when posts changes, the component will re-render:

var AllPosts = React.createClass({
  getInitialState() {
    // Start with an empty array of posts.
    // Ideally, you want this component to do the data fetching.
    // If the data comes from a non-react source, as in your example,
    // you can do `posts: this.props.posts`, but this is an anti-pattern.
    return { posts: [] }
  },

  componentWillMount() {
    // Fetch the initial list of posts
    // I'm assuming here that you have some external method that fetches
    // the posts, and returns them in a callback.
    // (Sorry for the arrow functions, it's just so much neater with them!)
    ajaxMethodToFetchPosts(posts => { 
      this.setState({ posts: posts });
    })
  },

  componentDidMount() {
    // Attach your scroll handler here, to fetch new posts 
    // In a real example you'll want to throttle this to avoid too many requests
    window.addEventListener('scroll', () => {
      ajaxMethodToFetchPosts( posts => {
        this.setState({
          posts: this.state.posts.slice().concat(posts)
        });
      });
    });
  },

  render() {
    // Render method unchanged :)
    return (
      <div>
        {this.props.data.map(function(element, i) {
          return <Post data={element} />
        })}
      </div>          
    );
  }
});

With other frameworks, you have to deal with scroll position (if the element gets completely re-rendered, the elements disappear momentarily and your scroll position is reset).

React's render function doesn't actually just render its output to the DOM; it compares the potential output with what's already there, and only applies the difference. This means that only new posts are added to the DOM, and your scroll position will remain unaffected.

Upvotes: 1

Related Questions