You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Navigation V6中useFocusEffect内使用useCallback触发无效Hook调用错误求助

解决React Navigation V6中useFocusEffect内使用useCallback触发的Invalid Hook Call错误

问题回顾

你按照React Navigation V6的useFocusEffect文档示例尝试在其内部使用useCallback,却触发了以下错误:

Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:

  1. React和React DOM版本不匹配
  2. 违反了Hooks使用规则
  3. 应用中存在多个React副本

你的代码中useFocusEffect的写法是这样的:

useFocusEffect(() => {
  React.useCallback(() => {
   console.log(latVal, longVal);
   fetchWeatherData();
   fetchForecastData();
  }, [latVal]);
});

错误原因分析

问题的核心是违反了React Hooks的调用规则:所有React Hooks(包括useCallback)必须直接在函数组件的顶层作用域调用,不能嵌套在普通函数、另一个Hook的回调函数内部。

你现在的写法是把useCallback放在了useFocusEffect的回调函数里,这相当于在一个普通函数内部调用Hook,完全不符合规则,所以React抛出了错误。

官方文档的示例是把useCallback作为useFocusEffect的直接参数,而不是嵌套在回调里面,你可能误解了示例的写法。

修复方案

我们需要调整代码结构,让所有Hooks都在组件顶层调用,同时保持useFocusEffect的正确用法:

步骤1:用useCallback包裹数据请求函数(可选但推荐)

为了避免组件每次渲染都创建新的请求函数,我们先把fetchWeatherData和fetchForecastData用useCallback包裹,并明确它们的依赖项:

const fetchWeatherData = React.useCallback(async () => {
  const requestOptions = {
    method: 'GET',
    headers: {'Content-Type': 'application/json'},
  };
  try {
    const response = await fetch(
      `https://api.openweathermap.org/data/2.5/weather?lat=${latVal}&lon=${longVal}&appid=${API_KEY}`,
      requestOptions,
    );
    const responseData = await response.json();
    console.log(responseData);
    setData(responseData);
  } catch (err) {
    console.log(err);
  }
}, [latVal, longVal, API_KEY]); // 依赖所有用到的外部变量

const fetchForecastData = React.useCallback(async () => {
  const requestOptions = {
    method: 'GET',
    headers: {'Content-Type': 'application/json'},
  };
  try {
    const response = await fetch(
      `https://api.openweathermap.org/data/2.5/forecast?lat=${latVal}&lon=${longVal}&appid=${API_KEY}`,
      requestOptions,
    );
    const responseData = await response.json();
    setForecastData(responseData.list);
  } catch (err) {
    console.log(err);
  }
}, [latVal, longVal, API_KEY]);

步骤2:修正useFocusEffect的写法

把useCallback直接作为useFocusEffect的参数,确保它在组件顶层作用域被调用:

useFocusEffect(
  React.useCallback(() => {
    console.log(latVal, longVal);
    fetchWeatherData();
    fetchForecastData();
  }, [latVal, longVal, fetchWeatherData, fetchForecastData]) // 依赖请求函数和相关变量
);

额外优化说明

  • 移除了原代码中await和.then()混合使用的写法,改用纯async/await,代码更清晰易读。
  • 确保所有依赖项都被添加到useCallback的依赖数组中,避免因依赖缺失导致的 stale closure(闭包过时)问题。

排除其他可能问题

从你的package.json来看:

  • React 18.1.0和React Native 0.70.1版本匹配,不存在版本不匹配问题。
  • 依赖中没有重复安装React的迹象,排除多个React副本的问题。

所以修复上述Hook调用位置的问题后,错误应该就能解决了。

内容的提问来源于stack exchange,提问作者Fashad Ahmed

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 15:57:33