React组件JSON未变更却重复触发数据变更提示问题求助
解决React中JSON数据未变更却持续触发更新提示的问题
这个问题我之前也碰到过!核心原因是JavaScript中对象/数组是引用类型,直接用!==或者===比较的是它们的内存引用地址,而不是实际内容。每次fetch返回的d[0]都是一个全新的对象实例,哪怕它的内容和this.state.Old_item完全一致,引用地址也不一样,所以你的判断条件会永远成立,导致每次都输出“data changed”。
下面给你几种可行的解决方案,按需选择:
方案1:比较关键属性(推荐,性能最优)
既然你渲染的是price_usd,那只需要比较这个核心字段就够了,不需要对比整个对象:
GetCryptoData (){ const dataURL = "https://api.coinmarketcap.com/v1/ticker/bitcoin/"; fetch(dataURL) .then(d => d.json()) .then(d => { // 只对比价格字段,只有真正变化时才更新 if (this.state.Old_item.price_usd !== d[0].price_usd) { this.setState({ Old_item: d[0] }) console.log("data changed"); } }) }
方案2:JSON.stringify转字符串比较(简单但有局限性)
如果需要对比整个对象的内容,可以把对象转成字符串后再比较。注意:这种方法不适合包含函数、undefined或者属性顺序可能变化的对象,但对API返回的纯数据对象很管用:
GetCryptoData (){ const dataURL = "https://api.coinmarketcap.com/v1/ticker/bitcoin/"; fetch(dataURL) .then(d => d.json()) .then(d => { if (JSON.stringify(this.state.Old_item) !== JSON.stringify(d[0])) { this.setState({ Old_item: d[0] }) console.log("data changed"); } }) }
方案3:深度比较函数(最严谨)
如果需要更严谨的深度对比,可以自己实现一个深度比较函数,或者使用lodash.isEqual(如果项目已经引入lodash的话)。这里给你一个简易版的深度比较函数:
// 新增深度比较方法 isEqual(obj1, obj2) { if (obj1 === obj2) return true; // 判断是否是对象/数组 if (typeof obj1 !== 'object' || obj1 === null || typeof obj2 !== 'object' || obj2 === null) { return false; } // 对比属性数量 const keys1 = Object.keys(obj1); const keys2 = Object.keys(obj2); if (keys1.length !== keys2.length) return false; // 递归对比每个属性 for (const key of keys1) { if (!keys2.includes(key) || !this.isEqual(obj1[key], obj2[key])) { return false; } } return true; } // 使用深度比较 GetCryptoData (){ const dataURL = "https://api.coinmarketcap.com/v1/ticker/bitcoin/"; fetch(dataURL) .then(d => d.json()) .then(d => { if (!this.isEqual(this.state.Old_item, d[0])) { this.setState({ Old_item: d[0] }) console.log("data changed"); } }) }
额外优化:避免内存泄漏
你的组件里用了setInterval,记得在组件卸载时清除定时器,防止内存泄漏:
componentDidMount() { this.GetCryptoData(); // 把定时器ID存到实例上 this.intervalId = setInterval(this.GetCryptoData.bind(this), 10000); }; componentWillUnmount() { // 清除定时器 clearInterval(this.intervalId); }
内容的提问来源于stack exchange,提问作者xenon
相关产品推荐
相关产品推荐

