为何React Hooks必须在函数组件内使用?
你遇到的报错直接命中了React Hooks最核心的设计规则——Hooks的运行完全依赖固定的调用顺序和组件的渲染上下文,下面给你拆解具体原因:
React靠调用顺序绑定组件状态
React内部不会给每个Hook实例加唯一标识,而是靠组件每次渲染时Hooks的调用顺序来对应状态。比如组件第一次渲染时,第一个useState对应内部状态列表的第一个位置,第二个useState对应第二个位置。如果在组件外调用useContext,这个Hook的调用完全脱离了组件的渲染周期,React没法把它的状态/上下文关联到任何组件,直接打破了这个顺序绑定的逻辑,自然报错。组件外不存在React的运行上下文
Hooks的功能(比如useContext读取上下文、useEffect执行副作用)都依赖当前组件的渲染上下文:useContext需要知道当前组件处于哪个上下文树中,useState需要把状态挂载到当前组件的实例上。组件外没有这个上下文环境,React根本不知道该为这个Hook分配什么资源、从哪里获取数据。自定义Hook是特殊的“规则延续”
报错里提到允许在自定义Hook里调用Hooks,是因为自定义Hook本质是Hooks逻辑的封装,它必须被调用在组件内部的顶层,调用顺序依然和组件内的其他Hooks保持一致,React依然能通过顺序追踪状态,所以不会破坏规则。
举个简单的反例:如果允许在组件外调用useState,这个状态不属于任何组件,既不会随组件渲染更新,也无法被组件访问,完全失去了React状态管理的意义。
内容的提问来源于stack exchange,提问作者Ben

