Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ajax/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
React.js组件生命周期、状态行为和JavaScript的异步性质_Javascript_Ajax_Reactjs_Async Await - Fatal编程技术网

React.js组件生命周期、状态行为和JavaScript的异步性质

React.js组件生命周期、状态行为和JavaScript的异步性质,javascript,ajax,reactjs,async-await,Javascript,Ajax,Reactjs,Async Await,我对预期结果和实际结果有异议。即使从组件willmount()调用fetchData()和fetchnumberOfCommits()方法,数组仍然没有数据。但是在最后,render方法被调用了两次,其中数组从API获得了数据。 在上述两种方法中,我都调用了setState()方法,其中它调用了render方法。 我的问题是,为什么数组在调用这两个方法时不立即获取数据?数组在什么点获取数据 首次装入组件时,以及收到数据且状态已更改时,将调用render方法。这就是为什么会看到render方法被调

我对预期结果和实际结果有异议。即使从
组件willmount()
调用
fetchData()
fetchnumberOfCommits()
方法,数组仍然没有数据。但是在最后,render方法被调用了两次,其中数组从API获得了数据。 在上述两种方法中,我都调用了
setState()
方法,其中它调用了render方法。 我的问题是,为什么数组在调用这两个方法时不立即获取数据?数组在什么点获取数据


首次装入组件时,以及收到数据且状态已更改时,将调用render方法。这就是为什么会看到render方法被调用两次

componentWillMount()
在React 16.3中被弃用。您应该使用
componentDidMount()
来获取数据,并且您应该期望您的组件在获取数据之前至少呈现一次,因此您需要在获取数据之前呈现
null
或加载状态。我提供了一个示例,说明如何检查它是否正确加载并显示加载消息

class App extends React.Component {

  constructor() {
    super();
    this.state = {
      check: true,
      repositories: [],
      commits: [],
    };
  }

  componentDidMount() {
    this.fetchData();
    this.fetchNumberOfCommits();
  }

  fetchData() { /*...*/ }
  fetchNumberOfCommits() { /*...*/ }

  isLoaded() {
    return this.state.respositories.length > 0;
  }

  render() {
    const { repositories } = this.state;

    if(isLoaded) {
      return repositories.map(repo => {
        return (
          <Api
            repo={repo.name}
            createdDay={repo.createdDay} 
          />
        );
      });
    }

    return <h1>Loading repos...</h1>;
  }
}
类应用程序扩展了React.Component{
构造函数(){
超级();
此.state={
检查:正确,
存储库:[],
提交:[],
};
}
componentDidMount(){
这是fetchData();
this.fetchNumberOfCommissions();
}
fetchData(){/*…*/}
fetchNumberOfCommissions(){/*…*/}
孤岛加载(){
返回this.state.respositories.length>0;
}
render(){
const{repositories}=this.state;
如果(已加载){
返回repositories.map(repo=>{
返回(
);
});
}
退货回购。。。;
}
}

如上所述,您应该将其从componentWillMount中删除,因为从16.3开始,该组件已被弃用。应该能够将它放入componentDidMount中,它将为您工作。

我也从
componentWillMount()
更改为
componentDidMount()
,但我遇到了同样的问题。原因是JavaScript的异步特性。当您使用承诺时,它不会等到您从API调用中获得结果。它只需按顺序运行代码,在得到数据之前遵守承诺。这就是为什么我得到了一个空数组,即使调用了函数

您可以使用
async/await
使代码同步,然后它将等待,直到您从API调用中获得结果。 如果运行下面的代码示例,您可以在控制台中看到结果,其中
fetchData1()
给出一个空数组,而
fetchData2()
给数组提供数据。此外,如果仔细检查控制台,您将看到当调用
setState()
函数时方法触发器

import React, { Component } from 'react';

class App extends Component {
  constructor(){
    console.log('This is from constructor');
    super();     
    this.state={
      repositories:[],
  }  
  }
  componentDidMount(){
    console.log('This is from componentDidMount');
    this.fetchData1();
    this.fetchData2();
  }
  fetchData1(){
        console.log('This is function is using promises');
        fetch('https://api.github.com/users/94ju/repos').then(results => results.json()).then(repositories =>this.setState({ 
          repositories
        })).then( 
          console.log( this.state.repositories),
          console.log(this.state)
        ) 
        console.log('End of using promises')

  }
  async fetchData2(){
    console.log('This is function is using async-await');
    const check =await fetch('https://api.github.com/users/94ju/repos');
    const checkjson =await check.json();
    console.log('Before setState');
    this.setState({ async_repositories: checkjson });
    console.log( this.state.async_repositories);
    console.log(this.state);
    console.log('End of async-await');
}
  render() {
    console.log("Starting render function");
    const repo =this.state;
    console.log(repo);
    console.log('Ending render function');
    return (
      <div>

      </div>
    );

  }
}

export default App;
import React,{Component}来自'React';
类应用程序扩展组件{
构造函数(){
log('这是来自构造函数');
超级();
这个州={
存储库:[],
}  
}
componentDidMount(){
log('这是来自componentDidMount');
this.fetchData1();
this.fetchData2();
}
fetchData1(){
log('这是函数正在使用承诺');
取('https://api.github.com/users/94ju/repos然后(results=>results.json())。然后(repositories=>this.setState({
存储库
}))。然后(
console.log(this.state.repositories),
console.log(this.state)
) 
console.log('使用承诺结束')
}
异步获取数据2(){
log('这是函数正在使用异步等待');
常量检查=等待取数('https://api.github.com/users/94ju/repos');
const checkjson=await check.json();
console.log('Before setState');
this.setState({async_repositories:checkjson});
log(this.state.async\u存储库);
console.log(this.state);
log('End of async await');
}
render(){
log(“启动渲染函数”);
const repo=this.state;
控制台日志(repo);
log(“结束渲染函数”);
返回(
);
}
}
导出默认应用程序;

您不应该获取componentWillMount上的数据,但如果您确实决定这样做,请使componentWillMount成为一个异步函数。您应该在ComponentDidMount上致电FetchNumberOfCommissions谢谢您的评论我得到了答案。下面的链接显示了如何使componentWillMount和asyn功能。()