0

I have a Next.js application with the following page:

import { useState, useEffect } from 'react';
import axios from 'axios';
import { withRouter } from 'next/router';

import NotFound from '@/pages';
import { Page, PostBlock } from '@/components';

const Main = ({ router }) => {
  const [postsData, setPostsData] = useState({ posts: [], page: 0, pages: 0 });

  function fetchData() {
    axios
      .get('/api/articles', {
        params: {
          page: router.query?.page,
          lang: router.locale,
          tag: router.query.tag,
        },
      })
      .then(response => {
        setPostsData(response.data);
      })
      .catch(error => console.log(error));
  }

  useEffect(() => {
    fetchData();
  }, []);

  // if (!postsData.posts.length) return <NotFound />;

  return (
    <Page title='Home' className='home-template'>
      <div id='grid' className='post-grid'>
        {postsData.posts?.map(post => {
          return (
            <PostBlock
              featured={post.featured}
              key={post.key}
            />
          );
        })}
      </div>
    </Page>
  );
};

export default withRouter(Main);

The api fetches some articles on component mount, and display them in the UI. So far so good.

I also want to display a component in case there are no articles to display or if the api fails, but if I uncomment the line

if (!postsData.posts.length) return <NotFound />;

the application ends up in an infinite loop.

How can I fix this?

2
  • Where does it loop? Does it fetch the data multiple times? Commented Jan 18, 2022 at 10:42
  • setPostsData(response.data); this is creating new object with response coming from api. In case if there are no posts, is the api response coming as empty array. If the posts value is not matching with array format then it is possible to throw a length Commented Jan 18, 2022 at 10:58

2 Answers 2

1

Try setting posts as empty array in case if the data is empty

if (!(postsData.posts||[]).length) return <NotFound />;
Sign up to request clarification or add additional context in comments.

Comments

0

You just need to conditional render your loop part like below:

 return (
    <Page title='Home' className='home-template'>
      <div id='grid' className='post-grid'>
        {
          (postsData?.posts||[]).length ?  
            <>
              {postsData.posts.map(post => {
                 return (
                    <PostBlock
                     featured={post.featured}
                     key={post.key}
                    />
                  );
                })
              }
            </> : <NotFound />
         }            
      </div>
    </Page>
  );

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.