React创建组件时传递变量:为动态生成的Screen组件分配ID
解决React动态组件分配唯一ID的问题
你的核心问题在于使用了全局变量ID,导致所有Screen组件共享同一个值,最终都会拿到循环结束后的最后一个i值。正确的做法是通过props为每个Screen传递独立的ID,以下是修正后的代码:
修正后的Screen.js
import React, { useEffect } from "react"; // 改为接收id作为props const Screen = ({ id }) => { useEffect(() => { // 使用props中的id而非全局变量 socket.on(id, async () => { console.log(id); }); // 记得清理socket监听,避免内存泄漏 return () => { socket.off(id); }; }, [id]); // 将id加入依赖数组,确保effect正确触发 return ( <canvas id={id} className='canvas' width={600} height={400}> </canvas> ); }; export default Screen;
修正后的List.js
import Screen from './Screen'; import React, { useEffect, useState } from "react"; const List = () => { const [state, setState] = useState([]); useEffect(() => { // 一次性构建所有Screen元素,避免多次调用setState const newScreens = Array.from({ length: 5 }, (_, i) => ( <Screen key={i} id={`screen-${i}`} /> )); setState(newScreens); }, []); return ( <div> {state} </div> ); }; export default List;
关键改进点
- 移除全局变量:通过props传递ID,每个
Screen组件拥有独立的ID值,不会互相干扰。 - 优化state更新:一次性构建组件数组后再调用
setState,避免多次异步更新导致的状态不一致。 - 添加清理函数:在
useEffect的返回函数中移除socket监听,防止组件卸载后仍存在无效监听,造成内存泄漏。 - 依赖数组正确配置:将
id加入useEffect的依赖数组,确保组件挂载时能正确绑定对应ID的socket事件。
内容的提问来源于stack exchange,提问作者Romanus
相关产品推荐
相关产品推荐

