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

React组件重渲染致背景图变更,useMemo无效该如何解决?

问题描述

我有一个React组件,会在页面每次访问时生成随机背景图,但不希望它在组件重渲染时更新。目前用户在输入框中输入文本时,背景图会随每次重渲染更换。我尝试使用useMemo Hook但未成功,请问我哪里操作有误?

export function RegisterLayout({ children, position = 'justify-center' }) {
  return (
        ...
          <img
            src={getBackgroundImage()}
            alt='' 
            className='w-100 absolute inset-0 m-auto box-border block h-0 max-h-full min-h-full w-0 min-w-full max-w-full border-none object-cover p-0'
          />
        ...
  )
}

const getBackgroundImage = () => {
  const backgroundImages = Array(backgroundImage1, backgroundImage2, backgroundImage3, backgroundImage4)
  const randomInt = Math.floor(Math.random() * backgroundImages.length)

  return backgroundImages[randomInt]
}

RegisterLayout.propTypes = {
  children: PropTypes.array,
  position: PropTypes.string
}

export default RegisterLayout
问题原因与解决方案

问题核心是你每次组件重渲染时都会调用getBackgroundImage(),每次调用都会生成新的随机数,导致背景图跟着变化。需要让随机背景图仅在组件首次挂载时生成一次,后续重渲染不再更新。

方案1:使用useState初始化函数

利用useState的初始化函数特性,它只会在组件首次挂载时执行一次:

import { useState } from 'react';
import PropTypes from 'prop-types';

export function RegisterLayout({ children, position = 'justify-center' }) {
  // 仅首次渲染时执行getBackgroundImage
  const [backgroundImage] = useState(() => getBackgroundImage());

  return (
        ...
          <img
            src={backgroundImage}
            alt='' 
            className='w-100 absolute inset-0 m-auto box-border block h-0 max-h-full min-h-full w-0 min-w-full max-w-full border-none object-cover p-0'
          />
        ...
  )
}

const getBackgroundImage = () => {
  // 修正数组创建方式,Array()构造函数写法错误
  const backgroundImages = [backgroundImage1, backgroundImage2, backgroundImage3, backgroundImage4];
  const randomInt = Math.floor(Math.random() * backgroundImages.length);

  return backgroundImages[randomInt];
}

RegisterLayout.propTypes = {
  children: PropTypes.array,
  position: PropTypes.string
}

export default RegisterLayout

方案2:正确使用useMemo

如果你之前尝试useMemo失败,大概率是没设置空依赖数组。正确写法如下,空数组意味着仅在首次渲染时计算值:

import { useMemo } from 'react';

// 组件内部
const backgroundImage = useMemo(() => getBackgroundImage(), []);

这个写法和useState初始化函数的效果完全一致。

额外修正点

你代码里用Array(backgroundImage1...)创建数组的写法是错误的,应该用数组字面量[],否则无法正确生成包含指定元素的数组。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 16:22:44