我想提醒JSON值是否发生更改,然后在状态下对其进行更新,然后再进行console.log

时间:2019-07-19 11:31:39

标签: reactjs

我正在寻找警报,如果JSON发生更改,那么它将更新状态并警告数据已更改。不幸的是,尽管JSON数据未更改,但此步骤循环显示“数据已更改”。

这是我的代码示例

import React, { Component } from 'react'

class Api extends Component {
    constructor(props) {
        super(props)    
        this.state = {
            Old_item: []
        }

    }
    GetCryptoData (){
        const dataURL = "https://api.coinmarketcap.com/v1/ticker/bitcoin/";
        fetch(dataURL)
        .then(d => d.json())
        .then(d => {
            if (this.state.Old_item !== d[0]) {
                this.setState({ Old_item: d[0] })
                console.log("data changed");                 
            }

        })

    }

    componentDidMount(nextState) {
        this.GetCryptoData();
        setInterval(this.GetCryptoData.bind(this), 10000);
    };

    render() {
        return (
            <div>                
                {this.state.Old_item.price_usd}
            </div>
        )
    }
}
export default Api

4 个答案:

答案 0 :(得分:0)

那是因为您试图比较两个对象。请参见下面的代码。

let a = {'a':1};
let b = {'a':1};
if(a!==b){
    alert('Not Same!');
}else{
    alert('Same!');
}

您认为它们相同吗?是的,它们是给我们的,但是对于JavaScript却不是,因为当您比较它们时,它们的引用并不相同。JavaScript所做的是比较它们的引用。

因此,最好是可以基于JSON中的某些属性进行比较或检查。

答案 1 :(得分:0)

您需要在当前代码中进行一些更改

  1. 您以错误的方式进行比较。这不是比较对象数组的正确方法。您需要比较键以检查值是否更改
  2. setState是异步的,因此console.log在状态为 组。因此,这就是控制台应位于setState的回调中的原因。

您的新代码如下所示

class Api extends Component {
constructor(props) {
    super(props)    
    this.state = {
        Old_item: []
    }

}
GetCryptoData (){
    const dataURL = "https://api.coinmarketcap.com/v1/ticker/bitcoin/";
    fetch(dataURL)
    .then(d => d.json())
    .then(d => {
        if (this.state.Old_item["INDEX"]["YOUR KEY"] !== d["INDEX]["YOUR KEY"]) {
            this.setState({ Old_item: d[0] },()=>{
             console.log("data changed"); 
             })

        }

    })

}

componentDidMount(nextState) {
    this.GetCryptoData();
    setInterval(this.GetCryptoData.bind(this), 10000);
};

render() {
    return (
        <div>                
            {this.state.Old_item.price_usd}
        </div>
    )
}}
export default Api

答案 2 :(得分:0)

我只是编写了一个比较两个对象值的函数,只要两个对象的结构相同即可。

尽管尚未完全优化,但可以为您完成工作。

function compareObject(obj1, obj2) {
  const keys = Object.keys(obj1);
  const result = [];
  keys.forEach(key => {
    if (obj1[key] === obj2[key]) {
      result.push(1);
    } else {
      result.push(0);
    }
  });
  if (result.indexOf(0) === -1) {
    return true;
  }
  return -1;
}

const a ={
"id": "bitcoin",
"name": "Bitcoin",
"symbol": "BTC",
"rank": "1",
"price_usd": "10326.8374041",
"price_btc": "1.0",
"24h_volume_usd": "24838329700.1",
"market_cap_usd": "184082454924",
"available_supply": "17825637.0",
"total_supply": "17825637.0",
"max_supply": "21000000.0",
"percent_change_1h": "-0.46",
"percent_change_24h": "6.27",
"percent_change_7d": "-11.22",
"last_updated": "1563537331"
};
const b = {
"id": "bitcoin",
"name": "Bitcoin",
"symbol": "BTC",
"rank": "1",
"price_usd": "10326.8374041",
"price_btc": "1.0",
"24h_volume_usd": "24838329700.1",
"market_cap_usd": "184082454924",
"available_supply": "17825637.0",
"total_supply": "17825637.0",
"max_supply": "21000000.0",
"percent_change_1h": "-0.46",
"percent_change_24h": "6.27",
"percent_change_7d": "-11.22",
"last_updated": "1563537331"
};

alert(compareObject(a, b));

GetCryptoData (){
const dataURL = "https://api.coinmarketcap.com/v1/ticker/bitcoin/";
fetch(dataURL)
.then(d => d.json())
.then(d => {
    if (compareObject(this.state.Old_item[0], d[0]) {
        this.setState({ Old_item: d[0] });
    }

})

}

答案 3 :(得分:0)

就像上面提到的每个对象一样,您不能像这样比较对象。因为对象不是原始文字。意味着它们是通过引用而不是通过值传递的。简单来说

let obj1 = { a: 1 };
let obj2 = { a : 1 };

obj1 !== obj2;

因此,我通常使用自己的不同功能来比较对象。如果只需要做一个浅表比较,那么下面的简单函数就足够了。如果您需要的不仅仅是浅层比较,那么您将需要一个更复杂的函数。

const areObjectsEqual = (obj1 = {}, obj2 = {}) => Object
  .keys(obj1).length === Object.keys(obj2).length
  && Object.keys(obj1).every(key => obj1[key] === obj2[key]);

代替使用:

  

如果(this.state.Old_item!== d [0])

只需

  

if(!areObjectsEqual(this.state.Old_item,d [0])

如果问题仍然存在,则可能是由于对象深层嵌套或由于状态的异步性质所致。因此,您将不得不考虑这些因素。