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

React项目中useEffect触发截图偶尔为null且函数多次执行问题求助

React自动截图功能问题修复方案

问题根源

  1. 截图结果偶尔为null
  • takeScreenShot为异步方法,React的状态更新不是同步生效,调用后立刻读取screenshot状态会拿到更新前的初始值null
  • 函数组件错误使用createRef,该API每次渲染都会生成新的ref实例,容易导致DOM绑定失效
  • 组件挂载初期可能存在DOM未渲染完成的情况,ref.current为空时传入截图方法也会返回null
  1. 函数多次执行
  • React18开发环境默认开启严格模式,空依赖的useEffect会被执行两次,属于框架正常设计,用于校验副作用逻辑的健壮性
  • 未处理异步逻辑导致的状态更新触发的重复渲染,也会引发逻辑重复执行

修复后完整代码

import { useRef, useEffect } from 'react';
import jwtDecode from 'jwt-decode';
import axios from 'axios';
// 保留原有useScreenshot、AuthService的导入逻辑

function Products() {
  // 替换createRef为useRef,保证组件生命周期内ref唯一
  const ref = useRef(null);
  const [screenShoot, takeScreenShot] = useScreenshot();
  // 新增标识位避免严格模式下重复触发截图
  const executedRef = useRef(false);

  const getImage = () => {
    // 增加DOM存在性判断,避免传空值
    if (ref.current) {
      takeScreenShot(ref.current);
    }
  };

  // 监听截图状态,只有拿到有效截图后再发起接口请求
  useEffect(() => {
    if (!screenShoot || !executedRef.current) return;
    const data = {
      id: jwtDecode(AuthService.getCurrentUser().accessToken).id,
      screenShoot
    };
    axios.post("http://localhost:8080/api/auth/screenshoot", data)
      .then((response) => {
        console.log(response.data);
      })
      .finally(() => {
        executedRef.current = false;
      });
  }, [screenShoot]);

  useEffect(() => {
    if (executedRef.current) return;
    executedRef.current = true;
    getImage();
  }, []);

  return (
    <div ref={ref}>
      Welcome user
    </div>
  )
}

关键修改说明

  • 替换createRef为useRef,适配函数组件的ref使用规范
  • 新增screenshot状态监听逻辑,等异步截图生成完成后再发起接口请求,避免读取空值
  • 新增ref标识位,屏蔽开发环境严格模式下的重复执行问题,该问题生产环境会自动消失
  • 增加DOM存在性校验,避免DOM未渲染完成时调用截图方法报错

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.10 17:45:01