1

I have a component in which I am trying to add pagination functionality. I have made good progress in the structure so far. I have category buttons, where when a category button is selected, the element below shows a list of posts within that category.

For the pagination functionality, I using the WordPress REST API to pull in 5 posts at a time for each category. I am trying to create a "load more" button after the 5th post, where onClick it will load the next 5 posts:

const Posts = ({ state, actions }) => {
  const [categories, setCategories] = useState([]);
  const [categoryId, setCategoryId] = useState();
  const [posts, setPosts] = useState([]);
  useEffect(() => {
    fetch(state.source.api + "/wp/v2/categories")
      .then(response => response.json())
      .then(data => {
        setCategories(data);
      })
  }, []);

  useEffect(() => {
    if (categoryId) {
      fetch(state.source.api + "/wp/v2/posts?categories=" + categoryId + "&per_page=5")
        .then((response) => response.json())
        .then((data) => {
          setPosts(data);
        });
    }
  }, [categoryId]);

  const [morePosts, setMorePosts] = useState([]);
  useEffect(() => {
    if (categoryId) {
      fetch(state.source.api + "/wp/v2/posts?categories=" + categoryId + "&per_page=5&page=" + 2)
        .then((response) => response.json())
        .then((data) => {
          setMorePosts(data);
        });
    }
  }, [categoryId]);

  return (
    <>
      {categories.length > 0 ? (
        categories.map((category, i) => {
          return (
            <button key={i} onClick={() => setCategoryId(category.id)}>{category.name}</button>
          )
        })
      ) : (
          <p>Loading...</p>
        )
      }

      <div>
        {posts.length === 0 ? (
          <p>No posts...</p>
        ) : (
          <>
            <ol>
              {posts.map((post, i) => {
              return (
                <li key={i}>{post.title.rendered}</li>
              )
            })}
            </ol>
            <button onClick={() => setMorePosts(category.id)}>Load More</button>
              {console.log(morePosts.map((post) => post.title.rendered))}
            </>
          )}
      </div>
    </>
  )
}

As you can see, under the last button I am consoling the array, and it does return the next 5 posts for the selected category. I am stuck on how to turn that array from the console into actually being shown on the page.

0

1 Answer 1

2

I would do it this way:

Load more button changes the page number. When page number is changed: useEffect fires and posts are refetched/rerendered based on page number param.

const [page, setPage] = useState(1);
const [posts, setPosts] = useState([]);

useEffect(() => {
    if (!categoryId) {
        return;
    }

    let url = `${state.source.api}/wp/v2/postscategories=${categoryId}&per_page=5"`;

    if (page > 1) {
        url += `&page=${page}`;
    }

    fetch(url)
        .then((response) => response.json())
        .then((data) => {
            setPosts([...posts, ...data]);
        });
  }, [categoryId, page]);

  <button onClick={() => { setPage(page + 1); }}>Load more</button>
Sign up to request clarification or add additional context in comments.

1 Comment

That does work, thank you! The way this loads, it overwrites the first five posts with the next five posts. Do you know how I would be able to concatenate the "next" posts at the end of the first posts?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.