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

React useEffect依赖项未发生变化时仍触发执行的问题

问题场景

现有如下React组件代码:

import React, { useState, useEffect } from 'react';
import { HousesType } from '@src/store';

export const Home = () => {
  const [houses, setHouses] = useState<HousesType[]>([]);

  useEffect(() => {
    console.log('Should it fire if properties has no length?');
  }, [houses.length])


  return <h1>Testing</h1>
}

实际运行时出现不符合预期的现象:houses数组初始长度为0,依赖项houses.length从组件初始化开始没有发生任何变更,组件首次渲染时依然触发了effect内的控制台日志打印。
运行现象截图

原因解释

这是React useEffect Hook的既定运行逻辑,不属于异常:

  • useEffect的执行时机分两类:组件首次挂载完成后的初始执行、组件更新阶段依赖项变更触发的重复执行
  • 依赖数组的作用仅为控制更新阶段是否触发effect重执行:更新渲染完成后,React会对依赖数组内的每一项做浅比较,只要有任意一项和上一轮渲染的值不同,才会重跑effect
  • 首次挂载阶段的effect执行不受依赖数组约束,无论依赖项初始值是什么、有没有变化,组件第一次渲染完成后都会执行一次传入useEffect的回调,这就是初始状态下日志被打印的根本原因。
跳过首次执行的实现方案

如果需要仅在houses.length后续真正发生变更时才执行回调、跳过首次挂载的默认执行,可以通过useRef存储挂载标记做判断:

import React, { useState, useEffect, useRef } from 'react';
import { HousesType } from '@src/store';

export const Home = () => {
  const [houses, setHouses] = useState<HousesType[]>([]);
  // 存储首次挂载标记
  const firstMountRef = useRef(true);

  useEffect(() => {
    // 首次挂载时标记为false,直接返回不执行后续逻辑
    if (firstMountRef.current) {
      firstMountRef.current = false;
      return;
    }
    console.log('仅当houses.length发生变化时触发');
  }, [houses.length])


  return <h1>Testing</h1>
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 23:33:26