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

为何在条件语句中使用React Hooks未触发报错?

问题

根据React Hooks规则,我们不得在条件语句中使用任何Hooks。但下述示例代码却能正常运行,我不清楚为何未触发报错。

能否有人解释为何在if条件中使用Hooks却没有报错?

import { useEffect, useState } from "react";

let trackChanges = true;

export default function Demo() {
    const [text1, setText1] = useState("First");
    function onText1Change(value:string){
        setText1(value);
        if (value.length > 8)
        {
            trackChanges = false;
        }
        else{
            trackChanges = true;
        }
    }
    if (trackChanges){
        useEffect(()=>
        {   return () => {
                document.title=`${text1}`;
            }
        }, [text1]);
    }
    return (
        <input onChange={e=>onText1Change(e.target.value)} value={text1}/>
    )
}

我在VS Code中编写这段代码,本以为会触发报错,但出乎意料的是它能正常运行,这与其他StackOverflow问题及React文档所述不符。只有当text1的值长度大于8时,才会在运行时崩溃。是不是我的lint设置有问题?为何未按照Hooks规则给出报错警告?

解答

一、为什么没触发lint报错?

Hooks的规则检查完全依赖eslint-plugin-react-hooks这个ESLint插件,如果你没安装或正确配置它,VS Code就不会自动检测到条件中使用Hooks的问题:

  • 先检查项目package.json的devDependencies里有没有eslint-plugin-react-hooks,没有的话需要手动安装
  • 再看ESLint配置文件(比如.eslintrc),要确保plugins数组包含react-hooks,同时开启react-hooks/rules-of-hooks和react-hooks/exhaustive-deps这两条规则

二、为什么初始能运行,长度超8才崩溃?

React是靠每次渲染时Hooks的调用顺序来跟踪状态的,这是Hook机制的核心要求:

  1. 初始状态下trackChanges为true,组件渲染时会按顺序调用useState→useEffect,顺序固定,React能正常跟踪状态,所以没报错
  2. 当输入文本长度超过8,trackChanges被设为false,下一次渲染时会跳过useEffect的调用,此时调用顺序变成只有useState,和之前的顺序不一致,直接破坏了React的状态跟踪逻辑,导致运行时崩溃
  3. 初始阶段只是“碰巧”没破坏顺序,属于错误用法下的侥幸运行,并非符合规则

三、正确的修复方式

不要在条件中包裹Hooks,把判断逻辑移到Hook内部,保证每次渲染时Hooks的调用顺序一致:

import { useEffect, useState } from "react";

export default function Demo() {
    const [text1, setText1] = useState("First");
    const [trackChanges, setTrackChanges] = useState(true);

    function onText1Change(value:string){
        setText1(value);
        setTrackChanges(value.length <= 8);
    }

    useEffect(()=>{
        return () => {
            // 把条件判断移到Hook内部
            if(trackChanges) {
                document.title=`${text1}`;
            }
        }
    }, [text1, trackChanges]);

    return (
        <input onChange={e=>onText1Change(e.target.value)} value={text1}/>
    )
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 10:55:34