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>
优化重渲染与状态管理
- 简化状态结构:
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" /> - 缓存事件处理函数:用
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
相关产品推荐
相关产品推荐

