呈现数据,该数据是从react-native中的API获取的

时间:2020-03-10 05:05:03

标签: javascript reactjs api react-native

我正在使用React-Native,但遇到一些问题,只能将数据从API渲染到render函数中。我正在运行节点JS,并表示要从SQL数据库中提取一些数据。这将返回如下所示的JSON:

{"routines":[{"routine_id":1,"name":"Morning Routine","start_time":"2020-03-09T14:24:38.000Z","end_time":"2020-03-09T15:24:44.000Z","is_approved":0}]}

我想遍历routines键并打印每个routine作为React中的组件。我并不真正在乎使用哪种类型的组件,我只想获取数据。我尝试了几种方法:

方法1:将componentDidMountfetch结合使用:

 constructor() {
    super();
    this.state = { routines: {} }
}

componentDidMount() {
    fetch('http://localhost:3000/routines')
    .then((response) => response.json())
    .then((responseJson) => {
        return responseJson;
    })
    .then( routines  => {
        this.setState({routines: routines});

    })
    .catch( error => {
        console.error(error);
    });
}


render() {
    console.log(this.state)
render中的

this.state记录了一个空对象,尽管代码的then(routines部分返回了正确的数据。

方法2:将所有内容放入componentDidMount

  async componentDidMount() {
    const response = await fetch("http://localhost:3000/routines")
    const json = await response.json()
    console.log('json');
    console.log(json);
    const routines = json.routines
    this.setState({routines})
}

同样,在render中记录状态不会产生任何结果,而在日志中记录从componentDidMount返回的json会返回有效数据。

render方法中,我也尝试过:

const { routines } = this.state;

然后routines出现为未定义状态。

方法3:直接调用函数来设置状态。

constructor() {
        super();
        this.state = { routines: this.fetchData() }
    }

这最终会返回一些奇怪的数据:

{"routines": {"_40": 0, "_55": null, "_65": 0, "_72": null}}

我认为这是因为react native不希望我这样做。

我只想要一种简单的方法来从API提取数据并在render中显示该数据。我经历了大约四篇教程,所有这些教程最终都以render方法的构造函数中的未定义或对象设置为默认值。我要疯了吗?感觉这是不可能的..?

3 个答案:

答案 0 :(得分:0)

由于提取是异步任务,因此在执行this.setState({routines})之后设置数据render()。设置this.forceUpdate()后,可以执行this.setState({routines})。设置数据后,这将重新执行render()

请参阅:https://reactjs.org/docs/react-component.html#forceupdate

However, debugging mode can also be the culprit.

答案 1 :(得分:0)

您做对了所有事情,只需使用render中的状态,您就会看到更新。

constructor() {
    super();
    this.state = { routines: [] }
}

render() {
    const { routines } = this.state

    return (
        <View>
            {routines.map(item => <Text>{item.name}</Text>)}
        </View>
    )
}

答案 2 :(得分:0)

可能是因为fetch调用是异步的,并且您的render方法可能在api调用加载它之前尝试使用它, 因此您的componentDidMount应该像

 componentDidMount() {
 this.setState({routines:null})
//fire an api call
fetch('http://localhost:3000/routines')
.then((response) => response.json())
.then((responseJson) => {

    return responseJson;
})
.then( routines  => {
    this.setState({routines: routines});

})
.catch( error => {
    console.error(error);
});

}

现在在渲染函数中,您应该首先确认例程不为null并具有一些有效值,例如

render(){
 if(this.state.routines !==null){
   //your code to render component
 }else{
   //your loading or error message
  }
}