manthonyg / hacker-news-clone

a soft hacker news clone built in react.js
0 stars 0 forks source link

Infinite scroll for comments #10

Open manthonyg opened 3 years ago

manthonyg commented 3 years ago

Right now there is only an infinite scroll for the best/new/top posts. Comments can be quite lengthy, sometimes over 200, so infinite scroll is also a requirement here.

bhargavgohil25 commented 3 years ago

how to run the app locally ?? can you help me with that ?

manthonyg commented 3 years ago

Hey @Bhargav252000 . To run locally you fork the repo => clone to your local machine => npm install and then npm run server

bhargavgohil25 commented 3 years ago

hey @manthonyg I am using this library called @closeio/use-infinite-scroll

and here is the code, but I think I am doing something wrong with this hasMore

can you point it out ?

/* eslint-disable no-console */
import React, { useState, useEffect } from 'react';
import queryString from 'query-string';
import moment from 'moment';
import { Link } from 'react-router-dom';
import styled from 'styled-components';
import { fetchComments, fetchItem } from '../../utils/api';
import Comment from '../Comments/Comment';
import Flex from '../common/Flex';
import UserInfoSkeleton from '../UserInfo/UserInfoSkeleton';
import Heading from '../common/Heading/Heading';
import PostSkeleton from '../Posts/PostSkeleton';
import useInfiniteScroll from '@closeio/use-infinite-scroll';

const StyledLink = styled(Link)`
  text-decoration: underline;
  color: #bb86fc;
  font-weight: 800;
`;

function SinglePost() {
  // eslint-disable-next-line no-restricted-globals
  const { id } = queryString.parse(location.search);

  const [comments, setComments] = useState([]);
  const [post, setPost] = useState(null);
  const [isLoading, setIsLoading] = useState(false);
  const [hasMore, setHasMore] = useState(false);
  const [loaderRef, scrollerRef] = useInfiniteScroll({ hasMore });

  useEffect(() => {
    setIsLoading(true);
    fetchItem(id)
      .then(userpost => {
        setPost(userpost);
        return fetchComments(userpost.kids || []);
      })
      .then(usercomments => {
        setIsLoading(false);
        setHasMore(usercomments.hasMore);
        setComments(usercomments);
      })
      .catch(error => {
        console.warn('There was a problem gathering these resources', error);
      });
  }, []);

  return (
    <>
      {isLoading ? (
        <>
          <PostSkeleton numberOfSkeletons={1} noEmoji />
          <UserInfoSkeleton numberOfSkeletons={3} />
        </>
      ) : (
        <>
          {post && (
            <>
              <Heading h4 noMargin>
                {post.title}
              </Heading>
              <Heading h5>
                by <StyledLink to={`/user?id=${post.by}`}>{post.by}</StyledLink>{' '}
                at {moment.unix(post.time).format('YYYY-MM-DD')}
                title: {post.title}
              </Heading>
            </>
          )}
          <Flex>
            {comments && comments.length ? (
              <div ref = {scrollerRef}>
                {comments.map(comment => (
                  <Comment
                    key={comment.id}
                    id={comment.id}
                    text={comment.text}
                    by={comment.by}
                    time={comment.time}
                  />
                ))}
                { hasMore && <div ref={loaderRef}>Loading..</div> }
              </div>
            ) : (
              <Heading>No Comments</Heading>
            )}
          </Flex>
        </>
      )}
    </>
  );
}

export default SinglePost;
manthonyg commented 3 years ago

Hey @Bhargav252000

I, unfortunately, went ahead and actually got this done over the weekend!

https://github.com/manthonyg/hacker-news-clone/commit/65574b8849da80ac11d936c9333010b3f4be0b7e If you would like to see the changes on your local copy, you can rebase your repo by checking out the master branch and then git rebase master.

I see that you are using a different library than I went with- I had used https://www.npmjs.com/package/react-infinite-scroll-component which is actually a component that takes in a list and acts on it independently, while I think your package is a custom hook (and probably a better solution overall!)

Eventually, I aim to write my own custom hook solution for this project instead of using a 3rd party package.

Do you have any suggestions on improvements you or I could make? I have been writing lots of cypress and jest tests to get the coverage up, but am definitely open to any cool addons you could think of.