React组件传参异常:map遍历后duckLocation参数值错误合并
React遍历数组传递Props时duckLocation参数异常的解决方法
问题根源
核心问题是对Array.map()的回调参数理解错误:map的回调函数接收的三个参数依次是当前数组元素、索引、原数组,而非你预期的duckLocation和duckPic。
在你的代码中:
ducks.map((duckLocation, duckPic, index) => ( <Duck location={duckLocation} picture={duckPic} key={index} /> ))
这里的duckLocation实际是数组中的整个鸭子对象({duckLocation: {...}, duckPic: 数字}),而duckPic其实是当前元素的索引值,你误以为它是对象里的duckPic属性,这就导致传递给Duck组件的location变成了整个对象。
另外你的SummonDuckButton组件存在异步setState的潜在问题:调用setLeft/setTop后立刻使用left/top值会拿到旧值,因为setState是异步更新的。
解决步骤
- 从map遍历的当前元素中解构出
duckLocation和duckPic属性,正确传递给组件 - 先计算随机坐标值,再同步更新状态和创建
duckLocation对象,避免异步问题
修正后的代码
SummonDuckWrapper 组件
export const SummonDuckWrapper = () => { const [ducks, setDucks] = useState([]) const addDuck = (duck, picture) => { setDucks([...ducks, { duckLocation: duck, duckPic: picture }]) } React.useEffect(() => { console.log('useEffect ducks', ducks) }); return ( <div> <SummonDuckButton addDuck={addDuck} /> {/* 解构当前元素,正确获取duckLocation和duckPic */} {ducks.map(({ duckLocation, duckPic }, index) => ( <Duck location={duckLocation} picture={duckPic} key={index} /> ))} </div> ) }
SummonDuckButton 组件
export const SummonDuckButton = ({ addDuck }) => { const [left, setLeft] = useState(0); const [top, setTop] = useState(0); useEffect(() => { setLeft(Math.floor(Math.random() * screen.width)); setTop(Math.floor(Math.random() * screen.height)); }, []); const summonDuck = () => { // 先计算随机值,再同步更新状态和创建duckLocation const newLeft = Math.floor(Math.random() * screen.width); const newTop = Math.floor(Math.random() * screen.height); setLeft(newLeft); setTop(newTop); const duckLocation = { left: newLeft + 'px', top: newTop + 'px' } const duckPic = Math.floor(Math.random() * 3); addDuck(duckLocation, duckPic) } return ( <button onClick={summonDuck}> Summon Duck </button> ) }
验证效果
修改后,传递给Duck组件的location会正确获取到仅包含left和top的对象,picture也会正确对应数组中对象的duckPic属性。
内容的提问来源于stack exchange,提问作者ambear
相关产品推荐
相关产品推荐

