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

使用react-hooks-global-state时按钮点击触发无效Hook调用错误

解决react-hooks-global-state的Invalid hook call错误

你的错误根源是违反了React Hooks的核心规则:Hooks只能在函数组件的顶层代码中调用,或者在自定义Hook的顶层调用,绝对不能在普通回调函数(比如按钮点击事件处理函数)里使用Hook。

问题代码分析

你写的changeValue是一个普通函数,既不是React组件也不是自定义Hook。当按钮点击触发它时,里面的useGlobalState调用不在函数组件的上下文里,直接触发了"Invalid hook call"错误。

而你在组件内部直接调用changeValue时能暂时运行,是因为此时changeValue的执行处于函数组件的顶层渲染流程中,Hook调用符合上下文要求,但这其实是错误用法——组件每次渲染都会执行changeValue,触发状态更新后又会重新渲染,形成无限循环,只是你没注意到这个问题。

两种可行的修复方案

方案1:在组件内获取setMyVar,传递给事件处理函数

直接在组件顶层拿到全局状态的更新方法,在事件回调里直接调用它,不需要在回调里再调用Hook:

import { React, useEffect } from 'react';
import { createGlobalState } from 'react-hooks-global-state';
import { Text, Button } from 'react-native';

const initialState = { myVar: 1 };
const { useGlobalState } = createGlobalState(initialState);

export default function App() {
    const [myVar, setMyVar] = useGlobalState('myVar');

    // 用useEffect包裹初始化赋值,避免无限重渲染
    useEffect(() => {
        setMyVar(10);
    }, []);

    // 直接在组件内定义事件处理函数,使用已获取的setMyVar
    const changeValue = () => {
        setMyVar(0);
    };

    return (
        <>
            <Text>{myVar}</Text>
            {/* React Native使用Button组件和onPress事件 */}
            <Button title="Set to 0" onPress={changeValue} />
        </>
    );
}

方案2:使用库提供的setGlobalState方法

react-hooks-global-state在创建全局状态时会导出setGlobalState方法,这个方法可以直接在普通函数里修改全局状态,不需要调用Hook:

import { React, useEffect } from 'react';
import { createGlobalState } from 'react-hooks-global-state';
import { Text, Button } from 'react-native';

const initialState = { myVar: 1 };
// 同时导出useGlobalState和setGlobalState
const { useGlobalState, setGlobalState } = createGlobalState(initialState);

export default function App() {
    const [myVar] = useGlobalState('myVar');

    useEffect(() => {
        setMyVar(10);
    }, []);

    const changeValue = () => {
        // 直接调用setGlobalState修改全局状态
        setGlobalState('myVar', 0);
    };

    return (
        <>
            <Text>{myVar}</Text>
            <Button title="Set to 0" onPress={changeValue} />
        </>
    );
}

额外注意事项

  • 你的代码里用了Web的<button>标签,在React Native环境下应该使用react-native提供的<Button>组件,并且事件属性是onPress而非onClick。
  • 组件内直接调用setMyVar(10)会触发无限重渲染,必须用useEffect包裹,添加空依赖数组确保只执行一次。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 06:30:45