React component returns list of mapped items, then disappears

Viewed 356

I have a React component that renders a list of items that are being mapped over, and shows the id for each item. When the component first loads, the list items appear, but then a second or two later disappears and in the console returns undefined.

The component being rendered is:

const Posts = ({ state }) => {
  const [categories, setCategories] = useState([]);
  const [categoryId, setCategoryId] = useState();
  const [page, setPage] = useState(1);
  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]);

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

    let url = state.source.api + "/wp/v2/posts?categories=" + categoryId + "&per_page=5";

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

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

  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) => {
                  console.log(post.id);
                  return (
                    <li key={i}>{post.id}</li>
                  )
                })}
              </ol>

              <button onClick={() => { setPage(page + 1); }}>Load more</button>
            </>
          )}
      </div>
    </>
  )
}

And the console shows:

enter image description here

I have a lot of code commented out above this component, so the line in the console is referring to console.log(post.id);.

Does anyone have an idea of what could be causing this?

1 Answers

This useEffect is not needed. Both useEffects on initial load trying to hit same endpoint with same url params.

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

And I think arrays are not merged correctly here:

try to replace:
setPosts([...posts, data]);

to:
setPosts([...posts, ...data]);
Related