如何更改提取呼叫和重新呈现屏幕?

时间:2019-11-06 08:58:18

标签: javascript reactjs rest react-native fetch

我有一个与PostgresDB通信的React Native App投放了ExpressJS REST API。

我有一个fetchcall,它可以返回一些我想在我的应用程序中显示的数据。它使用两个参数来调用路线。一个是我存储在AsyncStorage中的用户ID,另一个是存储在我的状态中的选定日期。

我的问题是,当日期状态更改时,应该更新获取网址,然后退还给定日期的数据。当前它没有重新渲染屏幕,但是日期改变了。有没有一种特定的方法如何告诉我的提取查询应重新呈现?

例如:`http://myip/api/hours/daydata/${realDate}/${userid}` 是我的fetchurl,realDate是this.state.date,而userid是AsyncStorage存储的用户ID。

`http://myip/api/hours/daydata/2019-11-06/138`这个URL为我提供了给定日期和用户所需的数据。

在按钮上单击我的日期状态更改为例如2019-11-07。 `http://myip/api/hours/daydata/2019-11-07/138`这将是下一步应获取的新网址,我希望重新渲染屏幕以查看更改。但是它不会重新渲染!

这里有一些代码:

 async fetchData() {
    let realDate = this.state.date;
    await getData("userid")      // asyncStorage gets userid correctly
      .then(data => data)
      .then(value => this.setState({ userid: value }))
      .catch(err => console.log("AsyncS_Error: " + err));

    const userid = this.state.userid;
    console.log("cpmDM id_ " + userid);


    await fetch(
      `http://myip/api/hours/daydata/${realDate}/${userid}`
      )
      .then(console.log("realD8_: " + realDate))
      .then(res => res.json())
      // .then(res => console.log(res))
      .then(res => {
        console.log(res[0].remark);
        return this.setState({ 
          remark: res[0].remark
        });
      }) 
      .catch(err => console.log(err));
  }


componentDidMount() {
    this.fetchData();
  }

我希望得到重新渲染,因为我在备注时调用了setState。 在第一个渲染中,从第一个选定日期开始的注释被打消了,但是当我更改日期时,注释保持不变并且不会更新。

想法:

是否可以记录当前的提取网址?我可能需要像componentWillUpdate这样的东西吗?

编辑:这是更新我的状态的方式:

dateForwardHandler = () => {
    console.log("Current Date:", this.state.date);

    const newDate = Moment(this.state.date).add(1, "d").format("YYYY-MM-DD");
    this.setState({ date: newDate.toString() });

    console.log("Current Date:", this.state.date);
  };

EDIT 2.0:

在dateBackHandler和dateForwardHandler内部调用fetchData()实际上向我显示了我需要它们的不同备注,但是不知何故它们会放假1天。如果我将日期追溯到25.10,则可以从26.10中得到评论,然后再回到24.10,则可以从25.10中得到。

似乎该组件在第一次按时不会更新,而在第二次按时就更新了,

编辑合并:非常感谢你们给我的所有帮助。

我想告诉您应用程序当前的运行方式。

dateForwardHandler = () => {
    console.log("Current Date:", this.state.date);

    const newDate = Moment(this.state.date).add(1, "d").format("YYYY-MM-DD");
    this.setState({ date: newDate.toString() });

    console.log("Current Date:", this.state.date);

    this.fetchData();   // THIS CALL IS NEW 
  };

通过调用this.fetchData();状态改变后,按下按钮后,我得到一些不同的注释,但是我遇到的问题是,它总是一天休息。因此,前端和fetchcall不会以某种方式同时更新。 但是我认为首先将state.date设置为新日期,然后调用fetchData ...

是正确的。

感谢到目前为止的所有帮助;)

3 个答案:

答案 0 :(得分:0)

您不必返回this.setState,所以不用

return this.setState({ 
 remark: res[0].remark
});

使用

this.setState({ 
 remark: res[0].remark
});

答案 1 :(得分:0)

为什么您需要状态为当前的日期,并在需要时每次都进行更新?你不能做:

let currentDate = Moment().add(1, "d").format("YYYY-MM-DD").toString()

这样,您不必在每次更新日期时都强制重新渲染,而在获取时仍随日期一起获取

答案 2 :(得分:0)

首先,我不会将两个等待放在一个异步函数中。可能是您的提取方法无法及时检索到您的userId。

关于重新渲染,请尝试首先返回fetchData(res.json)的结果,然后返回async函数外部的setState。

编辑:

正如您提到要在按钮单击上执行的操作,它看起来可能像这样:

fetchData = (url, method) => {
    let error;
    return fetch(url, {
      method: method,
      headers: {
        Accept: 'application/json',
        'Content-Type': 'application/json',
      },
    }).then((response) => {
      if (response.ok) {
        return response.json().then(response => ({ response })).catch((error) => { console.log("JSON cannot be parsed") });
      } 
      error = JSON.stringify(response);
      return ({ error });
    }).catch((error) => {
      console.log("Promise rejected");
    });
  }



onButtonPress = async () => {    
    const userid = this.state.userid;
    const realDate = this.state.realDate;
    const { response, error } = await this.fetchData('http://myip/api/hours/daydata/${realDate}/${userid}', 'GET'); 
    if (response) {
        console.log(response);
        this.setState({ 
          remark: response[0].remark
        });
    } else {
        console.error("Error: " + error);
    }
}