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

React点击按钮后组件多次重渲染,图片闪显后消失问题求助

问题分析与解决方案

核心问题:表单默认提交导致页面刷新

按钮位于<form>标签内,默认类型为submit,点击后会触发表单的默认提交行为——页面刷新。页面刷新后组件重新挂载,所有状态被重置,所以新图片刚显示就消失。

解决方法二选一:

  • 方法1:在点击事件中阻止默认行为
    修改getAMeme函数,添加阻止默认行为的逻辑:
    const getAMeme = (e)=>{
        e.preventDefault(); // 阻止表单提交刷新页面
        const randomNum = Math.floor(Math.random() * meme.length)
        const url = meme[randomNum].url
        setUrl(prevUrl =>({
            ...prevUrl, 
            randomImage: url
        }))
    }
    
  • 方法2:将按钮类型改为button
    明确指定按钮为非提交类型,避免触发表单默认行为:
    <button type="button" onClick={getAMeme}>Generate Meme</button>
    

优化重渲染与状态管理

  1. 简化状态结构:url状态无需用对象存储,直接存图片URL字符串即可,减少不必要的状态更新:
    // 替换原有的[url, setUrl]
    const [memeUrl, setMemeUrl] = useState('');
    
    对应修改getAMeme和图片标签:
    const getAMeme = (e)=>{
        e.preventDefault();
        const randomNum = Math.floor(Math.random() * meme.length);
        setMemeUrl(meme[randomNum].url);
    }
    
    <img src={memeUrl} alt="cool" />
    
  2. 缓存事件处理函数:用useCallback包裹getAMeme,避免组件每次渲染都重新创建该函数,减少无意义重渲染:
    const getAMeme = useCallback((e)=>{
        e.preventDefault();
        if (meme.length === 0) return; // 避免初始数据未加载时报错
        const randomNum = Math.floor(Math.random() * meme.length);
        setMemeUrl(meme[randomNum].url);
    }, [meme]);
    

修改后的完整代码

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

const Ui = () => {
    const [memes, setMemes] = useState([]);
    const [memeUrl, setMemeUrl] = useState('');

    useEffect(() => {
        fetch('https://api.imgflip.com/get_memes')
            .then(res => res.json())
            .then(data => setMemes(data.data.memes));
    }, []);

    const getAMeme = useCallback((e) => {
        e.preventDefault();
        if (memes.length === 0) return;
        const randomNum = Math.floor(Math.random() * memes.length);
        setMemeUrl(memes[randomNum].url);
    }, [memes]);

    return (
        <div className="ui">
            <form>
                <input placeholder="Enter first sentence" />
                <input placeholder="Enter second sentence" />
                <button onClick={getAMeme}>Generate Meme</button>
            </form>
            <div className="image">
                {memeUrl && <img src={memeUrl} alt="cool" />}
            </div>
        </div>
    );
};

export default Ui;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 00:10:20