reactjs - Error: React Hook "useRouter" - nextJsjavascript app not building - Stack Overflow

I am using nextJS and running into a little problem here and am not sure where I am going wrong. I'

I am using nextJS and running into a little problem here and am not sure where I am going wrong. I've built an app where everything works in dev. However, I am trying to build my app but I am receiving the error:

./pages/genre.js/[genre].js

13:18 Error: React Hook "useRouter" is called in function "genre" that is neither a React function ponent nor a custom React Hook function. React ponent names must start with an uppercase letter. React Hook names must start with the word "use". react-hooks/rules-of-hooks

The useRouter is located is on my page called [genre].js and the code is detailed below:

import React from "react";
import { useRouter } from "next/router";
import useFetchMovieGenreResults from "../../hooks/useFetchMovieGenreResults";
import { useState } from "react";
import useFetchTrendingCatagory from "../../hooks/useFetchTrendingCatagory";
import useFetchTopRatedCatagory from "../../hooks/useFetchTopRatedCatagory";

export default function genre() {
  const router = useRouter();
  const { genre } = router.query;

    
  if (genre == "Trending") {
    let mymovies = useFetchTrendingCatagory();

    return (
      <div>
        {/* <Navbar /> */}
        <div>{genre}</div>
        <Moviegenreresults movies={mymovies} />
      </div>
    );
  } else if (genre == "Top Rated") {
    let mymovies = useFetchTopRatedCatagory();

    return (
      <div>
        {/* <Navbar /> */}
        <div>{genre}</div>
        <Moviegenreresults movies={mymovies} />
      </div>
    );
  } else {
    let mymovies = useFetchMovieGenreResults(genre);

    return (
      <div>
        {/* <Navbar /> */}
        <div>{genre}</div>
        <Moviegenreresults movies={mymovies} />
      </div>
    );
  }

The official for Nextjs suggests using the useRouter to access the URL parameters

Why does this error occur? What am I missing? Any workarounds?

Update

I am trying to go with the solution below.

import React from "react";
import { useRouter } from "next/router";
import useFetchMovieGenreResults from "../../hooks/useFetchMovieGenreResults";
import { useState } from "react";
import useFetchTrendingCatagory from "../../hooks/useFetchTrendingCatagory";
import useFetchTopRatedCatagory from "../../hooks/useFetchTopRatedCatagory";

const useMovies = (genre) => {
  switch (genre) {
    case 'Trending':
      return useFetchTrendingCatagory()
    case 'Top Rated"':
      return useFetchTopRatedCatagory()
    default:
      return useFetchMovieGenreResults(genre)
  }
}

export default function Genre () {
  const router = useRouter();
  const { genre } = router.query;
  const mymovies = useMovies(genre)

  return (
    <div>
      {/* <Navbar /> */}
      <div>{genre}</div>
      <Moviegenreresults movies={mymovies} />
    </div>
  )
}

However I am still getting the errors below while trying to build my code

**./pages/genre.js/[genre].js 15:14 Error: React Hook "useFetchTrendingCatagory" is called conditionally. React Hooks must be called in the exact same order in every ponent render. Did you accidentally call a React Hook after an early return? react-hooks/rules-of-hooks

17:14 Error: React Hook "useFetchTopRatedCatagory" is called conditionally. React Hooks must be called in the exact same order in every ponent render. Did you accidentally call a React Hook after an early return? react-hooks/rules-of-hooks

19:14 Error: React Hook "useFetchMovieGenreResults" is called conditionally. React Hooks must be called in the exact same order in every ponent render. Did you accidentally call a React Hook after an early return? react-hooks/rules-of-hooks**

Would not the switch statement be considered a conditional render? Any workaround for this?

I am using nextJS and running into a little problem here and am not sure where I am going wrong. I've built an app where everything works in dev. However, I am trying to build my app but I am receiving the error:

./pages/genre.js/[genre].js

13:18 Error: React Hook "useRouter" is called in function "genre" that is neither a React function ponent nor a custom React Hook function. React ponent names must start with an uppercase letter. React Hook names must start with the word "use". react-hooks/rules-of-hooks

The useRouter is located is on my page called [genre].js and the code is detailed below:

import React from "react";
import { useRouter } from "next/router";
import useFetchMovieGenreResults from "../../hooks/useFetchMovieGenreResults";
import { useState } from "react";
import useFetchTrendingCatagory from "../../hooks/useFetchTrendingCatagory";
import useFetchTopRatedCatagory from "../../hooks/useFetchTopRatedCatagory";

export default function genre() {
  const router = useRouter();
  const { genre } = router.query;

    
  if (genre == "Trending") {
    let mymovies = useFetchTrendingCatagory();

    return (
      <div>
        {/* <Navbar /> */}
        <div>{genre}</div>
        <Moviegenreresults movies={mymovies} />
      </div>
    );
  } else if (genre == "Top Rated") {
    let mymovies = useFetchTopRatedCatagory();

    return (
      <div>
        {/* <Navbar /> */}
        <div>{genre}</div>
        <Moviegenreresults movies={mymovies} />
      </div>
    );
  } else {
    let mymovies = useFetchMovieGenreResults(genre);

    return (
      <div>
        {/* <Navbar /> */}
        <div>{genre}</div>
        <Moviegenreresults movies={mymovies} />
      </div>
    );
  }

The official for Nextjs suggests using the useRouter to access the URL parameters

Why does this error occur? What am I missing? Any workarounds?

Update

I am trying to go with the solution below.

import React from "react";
import { useRouter } from "next/router";
import useFetchMovieGenreResults from "../../hooks/useFetchMovieGenreResults";
import { useState } from "react";
import useFetchTrendingCatagory from "../../hooks/useFetchTrendingCatagory";
import useFetchTopRatedCatagory from "../../hooks/useFetchTopRatedCatagory";

const useMovies = (genre) => {
  switch (genre) {
    case 'Trending':
      return useFetchTrendingCatagory()
    case 'Top Rated"':
      return useFetchTopRatedCatagory()
    default:
      return useFetchMovieGenreResults(genre)
  }
}

export default function Genre () {
  const router = useRouter();
  const { genre } = router.query;
  const mymovies = useMovies(genre)

  return (
    <div>
      {/* <Navbar /> */}
      <div>{genre}</div>
      <Moviegenreresults movies={mymovies} />
    </div>
  )
}

However I am still getting the errors below while trying to build my code

**./pages/genre.js/[genre].js 15:14 Error: React Hook "useFetchTrendingCatagory" is called conditionally. React Hooks must be called in the exact same order in every ponent render. Did you accidentally call a React Hook after an early return? react-hooks/rules-of-hooks

17:14 Error: React Hook "useFetchTopRatedCatagory" is called conditionally. React Hooks must be called in the exact same order in every ponent render. Did you accidentally call a React Hook after an early return? react-hooks/rules-of-hooks

19:14 Error: React Hook "useFetchMovieGenreResults" is called conditionally. React Hooks must be called in the exact same order in every ponent render. Did you accidentally call a React Hook after an early return? react-hooks/rules-of-hooks**

Would not the switch statement be considered a conditional render? Any workaround for this?

Share Improve this question edited Sep 16, 2022 at 19:46 Time2learnagain asked Sep 15, 2022 at 20:14 Time2learnagainTime2learnagain 312 silver badges5 bronze badges 2
  • Please check the second part of my answer, I believe it answers it solves the hooks problem – Ameer Commented Sep 17, 2022 at 14:27
  • NextJS version ? – nifCody Commented Nov 5, 2022 at 17:46
Add a ment  | 

2 Answers 2

Reset to default 5

You simply need to rename your ponent to start with a capital letter, i.e., Genre. The reason for this, is that ponents must start with uppercase letters, and only ponents and hooks can make use of hooks (such as useRouter)

export default function Genre()

For the hook problem you can't conditionally call hooks or call them within blocks, they're a lot like import statements, they need to be called at the top of their parents (for the hook, the parent will be the function, i.e., you need to call hooks at the top of the ponent/function). To still do what you want to do, rather than conditionally calling the hook, you can conditionally pass in parameters using the ternary operator (https://developer.mozilla/en-US/docs/Web/JavaScript/Reference/Operators/Conditional_Operator). I remed reading into hook patterns (https://www.patterns.dev/posts/hooks-pattern/):

  const router = useRouter();
  const { genre } = router.query;
  // instead of calling the hook conditionally, change the parameter you're calling in the hook conditionally, this will fix the error you're getting with regards to conditionally calling hooks

  const mymovies = useFetchTrendingCategory(genre == "Trending" || genre == "Top Rated" ? undefined : genre)

    return (
      <div>
        {/* <Navbar /> */}
        <div>{genre}</div>
        <Moviegenreresults movies={mymovies} />
      </div>
    );

I can see 2 problem here.

The first one is the ponent name (as @Ameer said). Try to rename it to Genre.

Second one is the use of hook in a conditionally render. This is not a good practice.

You can refactor code like this:

import React from "react";
import { useRouter } from "next/router";
import useFetchMovieGenreResults from "../../hooks/useFetchMovieGenreResults";
import { useState } from "react";
import useFetchTrendingCatagory from "../../hooks/useFetchTrendingCatagory";
import useFetchTopRatedCatagory from "../../hooks/useFetchTopRatedCatagory";

export default function Genre () {
  const router = useRouter();
  const { genre } = router.query;
  const [movies, setMovies] = useState([]) // is that an array?

  useEffect(() => {
   let fetchedMovies

   switch (genre) {
     case 'Trending':
       fetchedMovies = useFetchTrendingCatagory()
     case 'Top Rated"':
       fetchedMovies = useFetchTopRatedCatagory()
     default:
       fetchedMovies = useFetchMovieGenreResults(genre)
   }

   setMovies(fetchedMovies)
  }, [genre])
    
  return (
    <div>
      {/* <Navbar /> */}
      <div>{genre}</div>
      <Moviegenreresults movies={movies} />
    </div>
  )
}

or like this:

import React from "react";
import { useRouter } from "next/router";
import useFetchMovieGenreResults from "../../hooks/useFetchMovieGenreResults";
import { useState } from "react";
import useFetchTrendingCatagory from "../../hooks/useFetchTrendingCatagory";
import useFetchTopRatedCatagory from "../../hooks/useFetchTopRatedCatagory";

const useMovies = (genre) => {
  switch (genre) {
    case 'Trending':
      return useFetchTrendingCatagory()
    case 'Top Rated"':
      return useFetchTopRatedCatagory()
    default:
      return useFetchMovieGenreResults(genre)
  }
}

export default function Genre () {
  const router = useRouter();
  const { genre } = router.query;
  const mymovies = useMovies(genre)

  return (
    <div>
      {/* <Navbar /> */}
      <div>{genre}</div>
      <Moviegenreresults movies={mymovies} />
    </div>
  )
}

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744993626a4605054.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信