Как правильно разбить данные на страницы в React с Firestore? - PullRequest
1 голос
/ 17 июня 2019

Когда я начинаю свой опыт работы с Firebase, я немного борюсь с нумерацией постов на моем блоге :(.

Я думаю, что вроде как понял документы из Google и знаю, какпереместить нумерацию страниц на следующую страницу, однако я абсолютно не знаю, как выполнить разбиение на страницы на предыдущей странице.

В принципе, я хотел иметь простой компонент нумерации страниц, который будет выглядеть примерно так: <1 23 [...]> (где вы можете разбивать страницы на страницы следующим и назад, используя стрелки).

Хорошо разбивать страницы на следующую страницу, но когда дело касается разбивки на страницы, я не могу найти никакого подходящего учебника посделайте это в чистом React.

Я пытался использовать различные методы из startAt, endAt, endBefore и т. д. Но результатом была либо ошибка, либо это возвращало меня на первую страницу (даже когда я был натретий или четвертый)

Я даже пытался найти первый объект в массиве и использовать его как endBefore, но это снова привело к разбиению на страницы на первой странице.

Вот так выглядит мой код прямо сейчас (да, я знаю, что pageNext () и pagePrev () одинаковы)

import React, { Component } from 'react'
import { withFirebase } from './Firebase'
import Post from './Post'

import '../scss/Post.scss'

class Posts extends Component {
    constructor(props) {
        super(props);
        this.state = {
            loading:false,
            posts:[],
            post_id:[],
            lastVisible:null,
            limit:2
        }

        this.handlePageNext = this.handlePageNext.bind(this);
    }
    componentDidMount() {
        let newPosts=[];
        let postsId=[];

        this.setState({ loading: true });

        this.props.firebase.posts()
        .orderBy('date', 'desc')
        .limit(2)
        .get().then(querySnapshot => {
            let lastVisible = querySnapshot.docs[querySnapshot.docs.length-1];
            this.setState({ lastVisible: lastVisible});

            querySnapshot.forEach(doc => {
                newPosts = newPosts.concat(doc.data());
                postsId = postsId.concat(doc.id);           
                this.setState({
                    posts:newPosts,
                    post_id:postsId,
                    loading:false
                });
            })
        })



    }

    handlePageNext() {
        let newPosts=[];
        let postsId=[];

        this.setState({ loading: true });

        this.props.firebase.posts()
        .orderBy('date', 'desc')
        .startAt(this.state.lastVisible)
        .limit(this.state.limit)
        .get().then(querySnapshot => {
            let lastVisible = querySnapshot.docs[querySnapshot.docs.length-1];

            this.setState({ lastVisible:lastVisible });
            querySnapshot.forEach(doc => {
                newPosts = newPosts.concat(doc.data());
                postsId = postsId.concat(doc.id);           
                this.setState({
                    posts:newPosts,
                    post_id:postsId,
                    loading:false
                });
            })
        })
    }

    handlePagePrev() {
        let newPosts=[];
        let postsId=[];

        this.setState({ loading: true });

        this.props.firebase.posts()
        .orderBy('date', 'desc')
        .startAt(this.state.lastVisible)
        .limit(this.state.limit)
        .get().then(querySnapshot => {
            let lastVisible = querySnapshot.docs[querySnapshot.docs.length-1];

            this.setState({ lastVisible:lastVisible});
            querySnapshot.forEach(doc => {
                newPosts = newPosts.concat(doc.data());
                postsId = postsId.concat(doc.id);           
                this.setState({
                    posts:newPosts,
                    post_id:postsId,
                    loading:false
                });
            })
        })
    }

    render() {
        return (
            <div className='posts'>
                <div className='row'>
                    {this.state.posts.map((post, i) => (
                        <Post 
                            key={i}
                            title={post.title}
                            author={post.author}
                            desc={post.desc}
                            text={post.text}
                            id={this.state.post_id[i]}
                            date={post.date}
                            imgURL={post.imgURL}/>
                    ))}

                    {this.state.loading && <p>Loading...</p>}
                    <button className='btn' onClick={() => this.handlePagePrev()}>&larr;</button>
                    <button className='btn' onClick={() => this.handlePageNext()}>></button>

                </div>

            </div>
        )
    }
}

export default withFirebase(Posts);

Я хотел сделать простую нумерацию страниц с помощью кнопок (слева)и стрелки вправо), но я борюсь с этим уже третий час и не могу найти правильного решения для этого.

Ответы [ 2 ]

1 голос
/ 17 июня 2019

Вы должны сохранить «lastVisible» и передать его startAfter ().2 функции, которые я написал ниже:

export const getMostRecentPostsFirstPage = (limit, specificUserId) => {
  if (!Number.isInteger(limit) || limit < 1) {
    throw new Error('limit must be a positive integer');
  }

  const collection = Firestore.collection('posts');
  let query = null;

  if (specificUserId) {
    query = collection
      .where('userId', '==', `${specificUserId}`)
      .orderBy('postedTimestamp', 'desc')
      .limit(limit);
  } else {
    query = collection.orderBy('postedTimestamp', 'desc').limit(limit);
  }

  return new Promise((resolve, reject) => {
    const posts = [];
    query
      .get()
      .then(snapshot => {
        const lastVisible = snapshot.docs[snapshot.docs.length - 1];
        snapshot.forEach(post => {
          posts.push(post.data());
        });
        const hasMore = posts.length == limit;
        resolve({ posts: posts, lastVisible: lastVisible, hasMore: hasMore });
      })
      .catch(error => reject(error));
  });
};
export const getMostRecentPostsNextPage = (lastVisible, limit, specificUserId) => {
  if (!lastVisible) {
    throw new Error('Need to provide lastVisible argument');
  }

  if (!Number.isInteger(limit) || limit < 1) {
    throw new Error('limit must be a positive integer');
  }

  const collection = Firestore.collection('posts');
  let query = null;

  if (specificUserId) {
    query = collection
      .where('userId', '==', `${specificUserId}`)
      .orderBy('postedTimestamp', 'desc')
      .startAfter(lastVisible)
      .limit(limit);
  } else {
    query = collection
      .orderBy('postedTimestamp', 'desc')
      .startAfter(lastVisible)
      .limit(limit);
  }

  return new Promise((resolve, reject) => {
    const posts = [];
    query
      .get()
      .then(snapshot => {
        const lastVisible = snapshot.docs[snapshot.docs.length - 1];
        snapshot.forEach(post => {
          posts.push(post.data());
        });
        const hasMore = posts.length == limit;
        resolve({ posts: posts, lastVisible: lastVisible, hasMore: hasMore });
      })
      .catch(error => reject(error));
  });
};

Используется Redx-сага, но вы поймете идею.

в первом запросе, не вызывайте "startAfter ()", ноделать на последующих запросах, и вы должны сохранять «lastVisible» между каждым вызовом.

1 голос
/ 17 июня 2019

Здесь - это стандартная нумерация страниц с использованием Firebase в реагировании.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...