错误:React Hook“useRouter” - nextJs/javascript 应用程序未构建

Tim*_*ain 3 javascript reactjs next.js react-hooks

我正在使用 nextJS 并在这里遇到了一个小问题,我不确定我哪里出了问题。我已经构建了一个应用程序,一切都可以在开发中运行。但是,我正在尝试构建我的应用程序,但收到错误:

./pages/genre.js/[流派].js

13:18 错误:在函数“genre”中调用 React Hook“useRouter”,该函数既不是 React 函数组件,也不是自定义 React Hook 函数。React 组件名称必须以大写字母开头。React Hook 名称必须以“use”一词开头。反应钩子/钩子规则

useRouter 位于我的页面上,名为 [genre].js,代码详细如下:

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>
    );
  }
Run Code Online (Sandbox Code Playgroud)

Nextjs官方建议使用useRouter来访问URL参数

为什么会出现这个错误?我缺少什么?有什么解决方法吗?

更新

我正在尝试使用下面的解决方案。

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>
  )
}
Run Code Online (Sandbox Code Playgroud)

但是,我在尝试构建代码时仍然收到以下错误

**./pages/genre.js/[genre].js 15:14 错误:React Hook“useFetchTrendingCatagory”被有条件地调用。React Hooks 必须在每个组件渲染中以完全相同的顺序调用。您是否在提前返回后不小心调用了 React Hook?反应钩子/钩子规则

17:14 错误:React Hook“useFetchTopRatedCatagory”被有条件地调用。React Hooks 必须在每个组件渲染中以完全相同的顺序调用。您是否在提前返回后不小心调用了 React Hook?反应钩子/钩子规则

19:14 错误:有条件地调用 React Hook“useFetchMovieGenreResults”。React Hooks 必须在每个组件渲染中以完全相同的顺序调用。您是否在提前返回后不小心调用了 React Hook?反应钩子/钩子规则**

switch 语句不会被视为条件渲染吗?有什么解决方法吗?

Ame*_*eer 5

您只需将组件重命名为以大写字母开头,即Genre。这样做的原因是组件必须以大写字母开头,并且只有组件和钩子才能使用钩子(例如useRouter

export default function Genre()
Run Code Online (Sandbox Code Playgroud)

对于钩子问题,您不能有条件地调用钩子或在块内调用它们,它们很像导入语句,需要在其父级的顶部调用(对于钩子,父级将是函数,即,您需要在组件/函数顶部调用钩子)。为了仍然做你想做的事情,而不是有条件地调用钩子,你可以使用三元运算符有条件地传入参数(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators /Conditional_Operator)。我建议阅读钩子模式(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>
    );
Run Code Online (Sandbox Code Playgroud)