交叉口观察器清除React状态?

时间:2019-04-06 15:38:11

标签: javascript reactjs intersection-observer

我正在使用Intersection Observer来查看div元素是否在视口中,该视口实际上是页面的底部。在useEffect挂钩中,我要从Firestore提取博客并保存到state,然后滚动到最下面的第二个提取函数运行,这将提取另一个博客。我将以前的博客和新的博客的状态设置为Blog,但是以某种方式,以前的博客是空数组。 它仅输出新博客,而旧博客消失了。

getBlogs正在从Firestore获取文档,并使用获取的博客创建新数组。

import React, { useState, useEffect } from 'react';
import { connect } from 'react-redux';
import BlogListItem from './BlogListItem';
import db from '../firebase/firebase';
import BlogFilters from './BlogFilters';
import loader from '../images/loader.gif';
import RecentFeed from './RecentFeed';
import BlogsContext from '../context/blogs-context';

let startDoc = null;

const getBlogs = docs => {
    const blogs = [];
    docs.forEach(doc => {
        blogs.push({
            id: doc.id,
            ...doc.data(),
        });
    });
    startDoc = docs[docs.length - 1];
    return blogs;
};

const firstFetchBlogs = async () => {
    const data = await db.collection('blogs').orderBy('createdAt', 'desc').limit(5).get();
    return getBlogs(data.docs);
};

const fetchBlogs = async () => {
    const data = await db.collection('blogs').orderBy('createdAt', 'desc').startAfter(startDoc).limit(5).get();
    return getBlogs(data.docs);
};

export const ReadBlogList = () => {
    const [ blogs, setBlogs ] = useState([]);
    const [ loading, setLoading ] = useState(true);
    const [ smallLoading, setSmallLoading ] = useState(false);
    const [ noMore, setNoMore ] = useState(false);

    const scrollElement = React.useRef();

    const paginateBlogs = () => {
        setSmallLoading(true);
        fetchBlogs()
            .then(newBlogs => {
                setBlogs([ ...blogs, ...newBlogs ]);
                setSmallLoading(false);
            })
            .catch(() => {
                setSmallLoading(false);
                setNoMore(true);
            });
    };
    const io = new IntersectionObserver(entries => {
        const ratio = entries[0].intersectionRatio;
        if (ratio > 0) {
            paginateBlogs();
        }
    });

    useEffect(() => {
        let didCancel = false;
        firstFetchBlogs().then(newBlogs => {
            if (!didCancel) {
                setBlogs(newBlogs);
                setLoading(false);
                io.observe(scrollElement.current);
            }
        });
        return () => {
            didCancel = true;
        };
    }, []);

    return (
        <div className="container read-blog-list">
            <BlogFilters />

            {loading && <img src={loader} alt="Loader" />}

            {!loading && (
                <BlogsContext.Provider value={{ blogs }}>
                    <div className="read-blog-list__content">
                        {blogs.length > 0 ? (
                            <div className="read-blog-list__blogs">
                                {blogs.map(blog => <BlogListItem to="read" key={blog.id} {...blog} />)}
                                <div ref={scrollElement} />
                            </div>
                        ) : (
                            noMore && <p className="text-grey-darkest text-center text-xl">No more blogs</p>
                        )}

                        <RecentFeed />

                        {smallLoading && (
                            <div className="flex items-center justify-center">
                                <img className="w-12 h-12" src={loader} alt="Loader" />
                            </div>
                        )}
                    </div>
                </BlogsContext.Provider>
            )}
        </div>
    );
};

const mapStateToProps = state => ({
    filters: state.filters,
});

export default connect(mapStateToProps)(ReadBlogList);

0 个答案:

没有答案