React 17:错误:无效的钩子调用。 Hooks 只能在函数组件的主体内部调用

Posted

技术标签:

【中文标题】React 17:错误:无效的钩子调用。 Hooks 只能在函数组件的主体内部调用【英文标题】:React 17: Error: Invalid hook call. Hooks can only be called inside of the body of a function component 【发布时间】:2021-07-12 20:35:30 【问题描述】:

用例

我正在写一段代码搜索电影的细节到https://themoviedb.org

代码是在 React 17.0.2 中使用 yarn、visual studio 代码编写的。

问题

我正在从 useEffect 调用一个函数,它将根据调用 TheMovieDB 的结果生成一个 json 文件

我收到以下错误,您能帮帮我吗? **错误:无效的挂钩调用。 Hooks 只能在函数组件的主体内部调用。 **

提前感谢您在此问题上投入的时间

browser_movie_db.js 中的useEffect

 useEffect(() => 
    if (slideRows.length > 0 && searchTerm.length > 2) 
      const searchResult = searchInTheMovieDB(category, searchTerm);
      if (searchResult.results.length > 0) 
        setSlideRows(searchResult);
       else 
        setSlideRows(slides[category]);
      
     else 
      setSlideRows(slides[category]);
      console.log("slideRows", slideRows);
    setSlideRows(slides[category]);
  , [category, searchTerm, slideRows, slides, theMovieDBApikey]);
    

selection-filter-themoviedb.js 中的 searchInTheMovieDB 函数

export function searchInTheMovieDB(media_type, query) 
  let result = ;
  if (media_type === "tv") 
    result = 
      tv: [
        
          title: `$media_type search result`,
          data: GetSearch(media_type, query),
        ,
      ],
    ;
   else 
    result = 
      movie: [
        
          title: `$media_type search result`,
          data: GetSearch(media_type, query),
        ,
      ],
    ;
  
  return result;

selection-filter-themoviedb.js 中的 GetSearch 函数

export function GetSearch(media_type, query) 
  const [content, setContent] = useState([]);
  useEffect(() => 

    console.log("GetSearch", `$endpoint.Search/$media_type?query=$query`);
    api
      .get(`$endpoint.Search/$media_type`, 
        params: 
          api_key,
          query,
        ,
      )
      .then((res) => 
        setContent(res.data.results);
      )
      .catch((error) => 
        console.error("error.message", error.message);
      );
  , [media_type, query]);
  return  [media_type]: content ;

错误 无效的钩子调用。

【问题讨论】:

每个调用不是组件的钩子的函数都可以命名为useXYZ(它本身就是一个钩子)。递归进行,直到找到对不在钩子中且不在组件中的钩子的调用。 也看看***.com/questions/53895455/… Hooks 在(函数)组件之外根本没有意义,因为它们与组件生命周期和其他特定于 React 的特性密切相关。您不仅不允许在不相关的函数中调用它们,而且绝对没有理由想要这样做。您似乎试图在发出 API 请求的函数中使用状态/效果 Hooks,我认为您误解了异步 JS 代码以及误解了 Hooks - 对于异步部分,请参阅here 【参考方案1】:

解决方案

我增加了useEffects的数量来识别进程:

    *searchTerm 发生变化 然后,调用 Web 服务 最终,slideRows 变量设置了新内容

PS:我创建了一个 async 函数从 web 服务获取数据


    const [searchResults, setSearchResults] = useState([]);

    import axios from "axios";
    const api = axios.create( baseURL: BASE_URL );

    async function getSearch(media_type, query) 
    api
      .get(`$endpoint.Search/$media_type`, 
        params: 
          api_key,
          query,
        ,
      )
      .then((res) => 
        setSearchResults(res.data.results);
      )
      .catch((error) => 
        console.error("error.message", error.message);
      );

  

  useEffect(() => 
    if (searchResults.length > 0) 
      setSlideRows(
        tv: [
          
            title: `$category search result`,
            data: searchResults,
          ,
        ],
      );
    
  , [category, searchResults]);

  useEffect(() => 
    if (slideRows.length > 0 && searchTerm.length > 2) 
      getSearch(category, searchTerm);
     else 
      setSlideRows(slides[category]);
    
  , [searchTerm, slides]);

  useEffect(() => 
    if (searchResults.length > 0 && searchResults.results?.length > 0) 
      setSlideRows(searchResults);
     else 
      setSlideRows(slides[category]);
    

    setSlideRows(slides[category]);
  , [searchResults]);

【讨论】:

以上是关于React 17:错误:无效的钩子调用。 Hooks 只能在函数组件的主体内部调用的主要内容,如果未能解决你的问题,请参考以下文章

Material UI 无效的钩子调用

遵循教程后,react-router-dom 调用的 Hook 无效

React - 错误:无效的钩子调用。 Hooks 只能在函数组件的主体内部调用

React + Antd + Rollup 组件库“错误:无效的钩子调用。钩子只能在函数组件的主体内部调用”

错误:无效的挂钩调用。钩子只能在函数组件的主体内部调用。 (React-hooks React-native)

React Native 错误:无效的钩子调用。 Hooks 只能在函数组件的主体内部调用