Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Change in the order of hooks when calling API inside useEffect

I have the following component:

const PostPage = () => {
  const [post, setPost] = useState(null);
  const [comments, setComments] = useState([]);
  const router = useRouter()
  
  useEffect(() => {
    if (router.isReady) {
      apiClient.get(`/posts/${router.query.id}/`)
      .then((response) => {
        setPost(response.data)
        apiClient.get(`/comments/`).then((response) => {
          setComments(response.data)
        })})
      .catch((error) => console.error('Error fetching post:', error));
    };
  }, [router.isReady]);

  if (!post) {
    return <p>Loading...</p>;
  }

  return (
    <Grid container spacing={2}>
      {PostDetails(post, comments)}
    </Grid>
  )
  
};

export default PostPage;

the Post Details component:

const PostDetails = (post={}, comments=[]) => {
const { title, author, content} = post;

const router = useRouter()
  return (
    <div>
      {/* <Button variant="outlined" color="primary" onClick={() => router.back()}>Close Post</Button> */}
      <Typography variant="h2">{title}</Typography>
      <Typography variant="subtitle1">Author: {author}</Typography>
      <Typography variant="body1" >{content}</Typography>
      <Typography variant="h3">Comments:</Typography>
      <List>
        {comments.map((comment, index) => (
          <Comment author={comment.author} text={comment.text} index={index}/>
        ))}
      </List>
    </div>
  );
};

export default PostDetails;

When the Post component loads I get this error(If needed I can post the full error):
Warning: React has detected a change in the order of Hooks called by PostPage.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Previous render Next render

  1. useState useState
  2. useState useState
  3. useContext useContext
  4. useEffect useEffect
  5. undefined useContext
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    at PostPage (webpack-internal:///./pages/posts/[id].jsx:20:76)

It does render correctly but I still want to fix the error.
It looks like it’s pointing at the api call inside the useEffect hook, but I’m not sure what’s wrong with it.
An interesting thing I found is that if I remove the use of nextjs router in the PostDetails component the error does not appear, but I need it to have a navigation functionality.

I tried to read about the rules of hooks, checked I always initialize them unconditionally, and inside the component. I didn’t find any info in the next router docs that are related to the issue.

>Solution :

You are calling your component as a regular function PostDetails(post, comments). Instead you need to call it as a JSX React Component, i.e. <PostDetails post={post} comments={comments} />, otherwise React can’t handle hooks correctly.

Just to give your more info, if we expand your code you are basically calling useRouter after your "loading" if block:

  if (!post) {
    return <p>Loading...</p>;
  }

  return (
    <Grid container spacing={2}>
      { // This call is basically inlined in runtime
        // because it's just a regular function
        PostDetails(post, comments)
        
        // It expands in something like this:
        const router = useRouter()
        
        // And then you use your router here
        // But this whole code comes after an `if` block
        // which is against the rules of hooks
      }
    </Grid>
  )
  
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading