反应意外的输出

时间:2018-05-26 11:43:08

标签: reactjs

我使用AJAX请求获取数据并将其存储到state中。然后我试图在控制台中打印它。我在下面的代码中得到空数组

state = { 
    addressOject: []
};

view = value => {
    fetch('http://127.0.0.1:8000/api/addresses/show/'+ value, {
        method: 'GET',
        headers: {
            'Accept': 'application/json',
            'Content-Type': 'application/json',
            'Authorization': 'Bearer ' + Auth.getToken(),
        },
        body: JSON.stringify()
    })
    .then((response) => response.json())
    .then((responseData) => {
        this.setState({ addressOject: responseData.data[0]});
    })        

    console.log(this.state.addressOject)
}

3 个答案:

答案 0 :(得分:0)

那是因为Promise是异步的。在then将使用来自服务器的响应触发之前,状态将使用setState(也是异步)更新,您的控制台日志已经运行。

您可以在setState回调函数中打印更新后的状态,该函数将在状态更新后运行:

this.setState(
  { addressOject: responseData.data[0]},
  () => console.log(this.state.addressOject)
);

此外,您可以使用asyncawait使代码更像是同步的:

view = async value => {
    let response = await fetch('http://127.0.0.1:8000/api/addresses/show/'+ value, {
        method: 'GET',
        headers: {
            'Accept': 'application/json',
            'Content-Type': 'application/json',
            'Authorization': 'Bearer ' + Auth.getToken(),
        },
        body: JSON.stringify()
    })
    let response = response.json();

    this.setState(
      { addressOject: responseData.data[0]},
      () =>  console.log(this.state.addressOject)
    );
}

答案 1 :(得分:0)

Fetch是异步的。这意味着它需要一些时间才能完成,但其余的代码会在那时执行。

您的this.state.addressObject一开始是空的。当你控制它时,你会得到初始状态,那时fetch实际上并没有提取数据,所以它给出了相同的结果。

如果您确认您的提取会返回一些数据,那么您可以这样检查。

if(this.state.addressObject.length > 0) // do your stuff now

或者如果你的fetch可能返回空arry那么你必须声明状态以获取

this.state = {
    addressObject: [],
    fetched: false,
}

现在在抓取时执行此操作,

view = value => {
    fetch('http://127.0.0.1:8000/api/addresses/show/'+ value, {
        method: 'GET',
        headers: {
            'Accept': 'application/json',
            'Content-Type': 'application/json',
            'Authorization': 'Bearer ' + Auth.getToken(),
        },
        body: JSON.stringify()
    })
    .then((response) => response.json())
    .then((responseData) => {
        this.setState({ addressOject: responseData.data[0], fetched: true});

    })        

    console.log(this.state.addressOject)
}

然后,只有在获取数据后才能检查数据。

if(this.state.fetched) // look for your data here

希望有所帮助:)

答案 2 :(得分:0)

<强>原因
由于这是一个异步操作,一旦执行获取请求,甚至在完成之前,就会执行console.log。

<强>修正
因此,您可以将日志记录语句放在.then中,以便在获得响应后,console.log将起作用。

 view = value => {
    fetch('http://127.0.0.1:8000/api/addresses/show/'+ value, {
        method: 'GET',
        headers: {
            'Accept': 'application/json',
            'Content-Type': 'application/json',
            'Authorization': 'Bearer ' + Auth.getToken(),
        },
        body: JSON.stringify()
    })
    .then((response) => response.json())
    .then((responseData) => {
        this.setState({ addressOject: responseData.data[0]},()=>{
          console.log(this.state.addressOject)
        });
    })         
}