React里用useRef做视差滚动为啥没效果?

A. 智慧 阅读 28

我照着教程用 useRef 和 useEffect 写了个简单的视差效果,但图片根本不动,是哪里写错了吗?

控制台也没报错,scrollY 的值看起来是对的,但 transform 样式就是没应用上。

const Parallax = () => {
  const ref = useRef(null);
  useEffect(() => {
    const handleScroll = () => {
      if (ref.current) {
        const scrollY = window.scrollY;
        ref.current.style.transform = <code>translateY(${scrollY * 0.5}px)</code>;
      }
    };
    window.addEventListener('scroll', handleScroll);
    return () => window.removeEventListener('scroll', handleScroll);
  }, []);

  return <img ref={ref} src="/bg.jpg" alt="parallax" />;
};
我来解答 赞 7 收藏
二维码
手机扫码查看
1 条解答
东方卫红
你的代码逻辑本身没问题,scroll 事件能触发,ref 也拿到了,问题很可能出在 CSS 那儿。

视差效果要生效,图片通常需要 position: fixed 或者 position: absolute 加上 top: 0 之类的定位,否则图片会跟着页面一起滚,你设置 transform 的时候它其实已经在视口外面了。

你检查一下图片的 CSS 样式,大概需要这样的配置:

.parallax-img {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
object-fit: cover;
will-change: transform;
}


另外提醒一下,直接改 DOM 的 style 在 React 里虽然能跑,但容易遇到 React 重新渲染时被覆盖的情况。更稳妥的做法是用 state:

const Parallax = () => {
const [offset, setOffset] = useState(0);

useEffect(() => {
const handleScroll = () => {
setOffset(window.scrollY);
};
window.addEventListener('scroll', handleScroll);
return () => window.removeEventListener('scroll', handleScroll);
}, []);

return (
<img
src="/bg.jpg"
alt="parallax"
style={{
transform: translateY(${offset * 0.5}px),
position: 'fixed',
top: 0,
width: '100%'
}}
/>
);
};


这样 React 能更好地管理样式更新,也不用担心被覆盖的问题。
点赞 1
2026-03-12 14:02