如何在无需重新呈现整个response /Node组件的情况下创建“Load More”特性?

时间:2022-08-01 20:12:03

I'm trying to create a simple poll app, where you can make new polls.

我正在尝试创建一个简单的投票应用程序,在那里你可以进行新的投票。

In the section 'MyPolls', I want it to render only the first 5 polls that I've made instead of rendering the entire list of polls.

在“我的民意调查”一节中,我希望它只显示我所做的前5个民意调查,而不是显示所有的民意调查。

At the bottom is a 'Load More' button, where upon clicking, loads another 5 polls and so on.

底部是一个“Load More”按钮,点击后会加载另外5个轮询等等。

I've been using Mongoose/MongoDB backend and my approach has been to use skip and limit.

我一直在使用Mongoose/MongoDB后端,我的方法是使用skip和limit。

I've managed to implement this feature, but the problem is the entire component re-renders, which is annoying for a user as you have to scroll down again the click the 'Load More' button.

我已经实现了这个特性,但问题是整个组件重新呈现,这对用户来说很烦人,因为您必须再次向下滚动“加载更多”按钮。

Here is my app: https://voting-app-drhectapus.herokuapp.com/

这是我的应用:https://voting-app-drhectapus.herokuapp.com/

(use can you these login details for convenience: username: riverfish@gmail.com password: 123)

(用户名:riverfish@gmail.com密码:123)

And then goto the My Polls page.

然后到我的民意调查页面。

MyPoll.js:

MyPoll.js:

import React, { Component } from 'react';
import { connect } from 'react-redux';
import * as actions from '../../actions';

class MyPolls extends Component {
  constructor(props) {
    super(props);
    this.state = {
      skip: 0
    };
  }

  componentDidMount() {
    this.props.fetchMyPolls(this.state.skip);
    this.setState({ skip: this.state.skip + 5 });
  }

  sumVotes(polls) {
    return polls.reduce((a, b) => {
      return a.votes + b.votes;
    });
  }

  loadMore(skip) {
    this.props.fetchMyPolls(skip);
    const nextSkip = this.state.skip + 5;
    this.setState({ skip: nextSkip });
  }

  renderPolls() {
    return this.props.polls.map(poll => {
      return (
        <div className='card' key={poll._id}>
          <div className='card-content'>
            <span className='card-title'>{poll.title}</span>
            <p>Votes: {this.sumVotes(poll.options)}</p>
          </div>
        </div>
      )
    })
  }

  render() {
    console.log('polls', this.props.polls);
    console.log('skip:', this.state.skip);
    return (
      <div>
        <h2>My Polls</h2>
        {this.renderPolls()}
        <a href='#' onClick={() => this.loadMore(this.state.skip)}>Load More</a>
      </div>

    );
  }
}

function mapStateToProps({ polls }) {
  return { polls }
}

export default connect(mapStateToProps, actions)(MyPolls);

Action creator:

行动的创造者:

export const fetchMyPolls = (skip) => async dispatch => {
  const res = await axios.get(`/api/mypolls/${skip}`);

  dispatch({ type: FETCH_MY_POLLS, payload: res.data });
}

Poll route:

调查路线:

app.get('/api/mypolls/:skip', requireLogin, (req, res) => {

    console.log(req.params.skip);

    Poll.find({ _user: req.user.id })
      .sort({ dateCreated: -1 })
      .skip(parseInt(req.params.skip))
      .limit(5)
      .then(polls => {
        res.send(polls);
      });
  });

Entire github repo: https://github.com/drhectapus/voting-app

整个github回购:https://github.com/drhectapus/voting-app

I understand that might method of implementing this feature might be the best possible solution so I'm open to any suggestions.

我知道实现这个特性的方法可能是最好的解决方案,所以我愿意接受任何建议。

1 个解决方案

#1


2  

It looks like the re-render is triggered by the fact that clicking the "Load More" link actually causes react router to navigate to a new route, causing the entire MyPolls component to re-render.

看起来重新呈现是由点击“Load More”链接而触发的,这实际上会导致react router导航到一个新路径,从而导致整个MyPolls组件重新呈现。

Just replace the <a href='#' onClick={...}> with <button onClick={...}>.

只需替换与 <按钮onclick = {…}> 。

If you don't want to use a button, you could also change the onClick function to

如果您不想使用按钮,也可以将onClick函数更改为

const onLoadMoreClick = e => {
    e.preventDefault(); // this prevents the navigation normally occuring with an <a> element
    this.loadMore(this.state.skip);
}

#1


2  

It looks like the re-render is triggered by the fact that clicking the "Load More" link actually causes react router to navigate to a new route, causing the entire MyPolls component to re-render.

看起来重新呈现是由点击“Load More”链接而触发的,这实际上会导致react router导航到一个新路径,从而导致整个MyPolls组件重新呈现。

Just replace the <a href='#' onClick={...}> with <button onClick={...}>.

只需替换与 <按钮onclick = {…}> 。

If you don't want to use a button, you could also change the onClick function to

如果您不想使用按钮,也可以将onClick函数更改为

const onLoadMoreClick = e => {
    e.preventDefault(); // this prevents the navigation normally occuring with an <a> element
    this.loadMore(this.state.skip);
}