React使用Socket.IO传数据到子组件无法动态渲染如何解决
报错说明
你看到的Cannot add node "1" because a node with that id is already in the Store报错是React DevTools浏览器扩展的已知bug,和你的业务代码无关,尝试更新扩展、重启浏览器或者暂时禁用再重新开启扩展即可消除该报错。
动态渲染失效原因&修复方案
你目前的写法存在3个核心问题导致渲染异常:
- 列表渲染没有添加唯一
key属性,React无法追踪列表节点的更新,会导致数据变化时视图不触发刷新 - 初始渲染时
response是空数组,直接在子组件取responseCurrency[0]会拿到undefined,同时你只写了第一个占位节点的渲染逻辑,看不到完整数据 - 父组件提前把数据转成JSX元素传递,不利于子组件做灵活的渲染逻辑处理,也会增加不必要的重渲染风险
修复后的代码
1. App组件修改
import React, { useState, useEffect } from "react"; import socketIOClient from "socket.io-client"; import Main from "./Main"; const ENDPOINT = "http://127.0.0.1:4001"; function App() { const [response, setResponse] = useState([]); useEffect(() => { const socket = socketIOClient(ENDPOINT); socket.on("tick", (data) => { setResponse(data); }); // 添加清理函数,组件卸载时断开socket连接避免内存泄漏 return () => socket.disconnect(); }, []); return ( <> <div style={{ textAlign: "center" }}> <h1>Tradair Coding Assignment</h1> {/* 直接传递原始数据数组,不要提前转成JSX */} <Main responseCurrency={response} /> </div> </> ); } export default App;
2. Main组件修改
import React from 'react'; import './Main.css'; class Main extends React.Component { render() { const { responseCurrency } = this.props; // 空数据判断,避免初始状态报错 if (!responseCurrency.length) return <div>加载中...</div>; return ( <div className="container"> {/* 列表渲染添加唯一key,有业务唯一id时优先用业务id,否则可暂用index */} {responseCurrency.map((item, index) => ( <div key={index} className="placeholder"> hello {item.currencyPairName} 买价:{item.prices.bid} 卖价:{item.prices.offer} </div> ))} </div> ); } } export default Main;
内容的提问来源于stack exchange,提问作者gali gurevich
相关产品推荐
相关产品推荐

