React输入时组件意外重渲染,如何实现仅点击提交后更新内容
问题根源
- 输入框输入时会更新父组件状态,触发父组件全局重渲染,所有子组件默认随父组件重渲染
- LovePoem组件没有缓存随机选中的诗歌,每次渲染都会重新随机选取,导致诗歌不停切换
修改步骤
1. 修复子组件重渲染问题
给LovePercentContent和LovePoem两个子组件包裹React.memo,让它们仅在传入的data属性发生变化时才重渲染,同时把随机选诗逻辑放到useEffect里,仅在诗歌列表更新时才重新选取:
// 以LovePoem组件为例,LovePercentContent做相同处理 import React, { memo, useState, useEffect } from 'react'; const LovePoem = ({ data }) => { const [selectedPoem, setSelectedPoem] = useState(null); // 仅在data变化时才重新随机选取诗歌 useEffect(() => { if (Array.isArray(data) && data.length > 0) { const randomIndex = Math.floor(Math.random() * data.length); setSelectedPoem(data[randomIndex]); } }, [data]); if (!selectedPoem) return null; // 原有渲染逻辑,使用selectedPoem渲染内容 return ( <div className="love-poem"> {/* 渲染诗歌内容 */} </div> ) } export default memo(LovePoem);
2. 修正按钮点击事件的错误写法
你之前尝试的两种按钮写法都有问题:
- 第一种
onClick={() => handleSubmit(e)}:没有正确捕获事件参数e,会报错 - 第二种
onClick={() => handleSubmit}:没有执行handleSubmit函数,点击按钮无反应
直接使用你现有代码里的写法即可:
<button type="submit" className="btn" onClick={handleSubmit}> Get Poem </button>
3. 可选优化:使用useCallback稳定事件函数引用
如果要进一步优化,可以用useCallback包裹父组件的事件处理函数,避免每次渲染生成新的函数引用:
// 导入useCallback import React, { useState, useCallback } from "react"; // 包裹handleSubmit const handleSubmit = useCallback((e) => { // 原有逻辑不变 }, [yourName, yourCrushName]); // input的onChange也可以做相同处理 const handleYourNameChange = useCallback((e) => { setYourName(e.target.value); }, []); const handleCrushNameChange = useCallback((e) => { setYourCrushName(e.target.value); }, []);
4. 修复小bug
你代码中非yourSwitch分支的第二个输入框name属性写错了,修正为:
<input name="yourCrushName" value={yourCrushName} placeholder="Your Crush's Name" onChange={handleCrushNameChange} />
改完之后,只有点击提交按钮、yourLovePercent和yourLovePoems更新时,两个子组件才会重渲染,输入过程中不会再出现诗歌乱跳的问题。
内容的提问来源于stack exchange,提问作者cod3rShea
相关产品推荐
相关产品推荐

