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

React按滚动高度移动图片时useEffect识别条件渲染div id报错如何解决

问题根源

你遇到的报错核心是两个问题:

  1. 你给同一个DOM元素动态切换id,任意时刻页面上只会存在moveLeft或moveRight中的一个元素,你在滚动回调中同时获取两个id的元素,必然有一个返回null,调用.style属性时就会抛出空引用错误。
  2. 你的useEffect依赖数组为空,只会在组件首次挂载时执行一次,后续display状态更新也不会重新绑定事件,逻辑不会同步更新。

优化方案

不需要动态切换id,直接用useRef绑定目标元素,在滚动回调中直接根据当前滚动高度计算位移方向即可,逻辑更简洁也不会出现找不到元素的问题。

修改后完整代码:

import { useState, useEffect, useRef } from 'react';

export default function App() {
  const [display, setDisplay] = useState(false);
  // 用ref绑定目标元素,不需要依赖id获取
  const imgWrapRef = useRef(null);

  useEffect(() => {
    const changeBackground = () => {
      const value = window.scrollY;
      // 先判断元素存在再操作,避免报错
      if (!imgWrapRef.current) return;

      if (value > 600) {
        setDisplay(true);
        // 滚动超过600px时向右移动,减去600阈值避免位移跳变,可自行调整系数修改移动速度
        imgWrapRef.current.style.transform = `translateX(${(value - 600) * 0.5}px)`;
      } else {
        setDisplay(false);
        // 滚动不足600px时向左移动
        imgWrapRef.current.style.transform = `translateX(-${value * 0.5}px)`;
      }
    };

    window.addEventListener("scroll", changeBackground);
    return () => window.removeEventListener("scroll", changeBackground);
  }, []);

  return (
    <>
      <div className="App">
        <div className="inflow">
          <div className="positioner">
            <div className="fixed">
              {/* 绑定ref,不需要动态改id */}
              <div ref={imgWrapRef}>
                <img
                  alt="passport"
                  src="https://cdn.britannica.com/87/122087-050-1C269E8D/Cover-passport.jpg"
                />
              </div>
            </div>
          </div>
        </div>
      </div>
      <div className="App2"></div>
      <div className="App2"></div>
    </>
  );
}

注:原代码中的class属性已统一改为React要求的className,避免样式不生效的问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 06:30:00