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

React Native使用useRecoilValue报Invalid hook call错误如何解决

报错原因

你的代码触发Invalid hook call的核心原因是违反了React Hook的调用规则:useRecoilValue是React Hook,只能在React函数组件顶层或者自定义Hook(函数名必须以use开头)顶层调用,你当前写的ListFunction是普通工具函数,在内部调用Hook属于非法使用。

修复方案

提供两种可选修复方式,可根据你的业务场景选择:

方案1:改造为自定义Hook

将工具函数改为符合规范的自定义Hook,直接在内部调用Recoil相关Hook:

// List.fn.js 改造后代码
import { AsyncStorage } from "react-native";
import { useRecoilValue } from "recoil";
import { listDataViewer } from "../State";

// 函数名以use开头,符合自定义Hook命名规则
export const useSaveList = (listName) => {
  const listID = Date.parse(new Date());
  const newListData = {
    ID: listID,
    Name: listName
  };
  // 合法调用Hook
  const list = useRecoilValue(listDataViewer);

  const saveList = async () => {
    try {
      if (!list) {
        await AsyncStorage.setItem('list', JSON.stringify([list]));
      } else {
        await AsyncStorage.setItem('list', JSON.stringify([newListData, ...list]));
      }
    } catch (error) {
      console.log(error);
    }
  }
  return { saveList }
}

组件内使用方式:

// 业务组件中调用
import { useSaveList } from './List.fn.js'

const YourComponent = () => {
  // 在组件顶层调用自定义Hook
  const { saveList } = useSaveList('你的列表名称')

  const handleSubmit = () => {
    saveList()
  }

  // 其余组件逻辑
}

方案2:把Hook调用移到组件层

不需要改动工具函数的核心逻辑,仅将Recoil取值逻辑移到调用该工具的组件内部,把取到的list作为参数传入工具函数:

// List.fn.js 改造后代码
import { AsyncStorage } from "react-native";

// 移除Hook调用,新增list入参
export const ListFunction = async (listName, list) => {
  const listID = Date.parse(new Date());
  const newListData = {
    ID: listID,
    Name: listName
  };
  try {
    if (!list) {
      await AsyncStorage.setItem('list', JSON.stringify([list]));
    } else {
      await AsyncStorage.setItem('list', JSON.stringify([newListData, ...list]));
    }
  } catch (error) {
    console.log(error);
  }
}

组件内使用方式:

// 业务组件中调用
import { useRecoilValue } from 'recoil'
import { listDataViewer } from '../State'
import { ListFunction } from './List.fn.js'

const YourComponent = () => {
  // 在组件顶层合法调用Hook
  const list = useRecoilValue(listDataViewer)

  const handleSubmit = async () => {
    // 把list作为参数传入工具函数
    await ListFunction('你的列表名称', list)
  }

  // 其余组件逻辑
}
额外排查项

如果修改后仍有报错,可排查以下两点:

  • 确保你的App根组件外层包裹了RecoilRoot组件,这是Recoil运行的前提
  • 高版本React Native已经将AsyncStorage从核心库移除,如果你使用的是RN 0.60+版本,建议替换为@react-native-async-storage/async-storage官方维护包,避免出现兼容问题

内容的提问来源于stack exchange,提问作者bash.ruv

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.13 17:12:03