React组件useEffect初始渲染未触发 传入number prop切片数组不生效
问题根源
- 使用
splice直接修改原始data数组:splice为原地修改方法,会永久改变全局data的内容,报错后修复能正常显示8个元素是热重载时读取了已被修改的data,属于异常表现,不是代码逻辑正确导致的。 - 首次渲染逻辑顺序问题:组件首次渲染会先执行
useState初始化,此时deck赋值为完整的16条数据,useEffect在组件挂载完成后才会执行,且直接修改原数组的操作不会改变数组引用,React检测不到状态变化,不会触发重渲染,因此页面始终展示16条数据。 - 依赖数组配置错误:
useEffect依赖数组为空,仅会执行一次,后续numberprop 变更时不会重新裁剪数组。
修复方案
推荐使用useMemo直接基于prop计算裁剪后的数组,无需额外使用useState和useEffect,性能更优且逻辑更清晰,slice方法不会修改原数组,避免全局污染:
import { useMemo } from 'react'; // 假设data为外部导入的长度为16的原始数组 const Images = (props) => { const deck = useMemo(() => { const count = parseInt(props.number, 10) || 0; // slice不会修改原数组,返回新的裁剪后数组 return data.slice(0, count); }, [props.number]); return ( <> <div className="img-container"> {deck.map(object => <div className="img-on" key={object.id}><img src={object.src} alt=""/></div>)} </div> </> ); } export default Images;
如果需要保留useState+useEffect的写法,可参考以下实现:
import { useState, useEffect } from 'react'; const Images = (props) => { const [deck, setDeck] = useState([]); useEffect(()=>{ const count = parseInt(props.number, 10) || 0; const slicedData = data.slice(0, count); setDeck(slicedData); }, [props.number]) // 将number加入依赖,参数变化时自动更新裁剪结果 return ( <> <div className="img-container"> {deck.map(object => <div className="img-on" key={object.id}><img src={object.src} alt=""/></div>)} </div> </> ); } export default Images;
内容的提问来源于stack exchange,提问作者mateuszlaczynski
相关产品推荐
相关产品推荐

