React的总初学者。 我正在尝试在React中解决这种情况的标准方法。
我正在访问一个api,所有数据都可以正常返回,除了我试图将数据设置为组件的状态,并且render()方法在返回任何数据之前先引用该状态,因此该状态属性被定义为“ null”。
在下面的代码示例中,您可以看到我正在登录到控制台,尽管情况如此,但第二条日志是从浏览器返回的,而第二条日志是将setState用作API数据的。
尽管使用.then(),但有关为什么会发生这种情况的任何帮助/说明也将得到赞赏。
谢谢。
PS:为简化起见,我删除了TeamList组件,但是像“第二个日志”一样,该组件在实际提取数据之前就已呈现。
import React, { Component } from 'react';
class App extends Component {
constructor(props) {
super(props);
this.state = {
data: null,
}
}
componentDidMount() {
const uri = 'http://api.football-data.org/v2/competitions/PL/teams';
let h = new Headers()
h.append('Accept', 'application/json')
h.append('X-Auth-Token', 'XXXXXXXXXXXXXXXXXXXX')
let req = new Request(uri, {
method: 'GET',
headers: h,
mode: 'cors'
})
var component = this;
fetch(req)
.then( (response) => {
return response.json()
})
.then( (json) => {
this.setState({ data: json })
})
.then( (json) => {
console.log( 'second log', this.state.data )
})
.catch( (ex) => {
console.log('parsing failed', ex)
})
console.log( 'first log', this.state.data )
}
render() {
return (
<div>
<div className="App">
<TeamList list={this.state.data} />
</div>
</div>
);
}
}
export default App;
答案 0 :(得分:2)
安装组件时,它会立即以初始状态(您在构造函数中设置的状态)呈现。然后,稍后,当您调用setState
时,状态将被更新,并且组件将被重新渲染。因此,在state.data
不为空之前显示“正在加载...”之类的内容很有意义:
render() {
return (
<div>
<div className="App">
{this.state.data ? <TeamList list={this.state.data} /> : "loading..." }
</div>
</div>
);
}
由于setState
不会返回承诺,因此现在另外的日志记录无法按预期进行,所以:
.then( (json) => {
this.setState({ data: json })
})
.then( (json) => {
console.log( 'second log', this.state.data )
})
实际上与以下内容相同:
.then( (json) => {
this.setState({ data: json })
console.log( 'second log', this.state.data )
})
,并且仍将null
记录为setState
是异步的,这意味着调用它不会立即更改this.state
而是何时。要正确记录它,请使用回调:
then( (json) => {
this.setState({ data: json }, () => {
console.log( 'second log', this.state.data )
});
})
答案 1 :(得分:1)
您需要在render()的开始处添加以下内容:
if (this.state.data === null) {
return false;
}
因此您的代码应为:
render() {
if (this.state.data === null) {
return false;
}
return (
<div>
<div className="App">
<TeamList list={this.state.data} />
</div>
</div>
);
}
render()被立即调用,但是您希望它返回false,直到this.state.data有数据为止
答案 2 :(得分:0)
一个想法:
import React, { Component } from 'react';
class App extends Component {
constructor(props)
{
super(props);
this.state = {
data: null,
};
}
componentDidMount()
{
fetch('http://api.football-data.org/v2/competitions/PL/teams')
.then(response => response.json())
.then(data => this.setState({ data }));
}
render() {
return (
<div>
<div className="App">
<TeamList list={this.state.data} />
</div>
</div>
);
}
}
export default App;
TeamList:
class TeamList extends React.Component {
constructor(props) {
super(props);
}
render(){
return (
<ul>
{
this.props.list.map((element, i) => {
return (
<li className="un-res t_d " key={i}>{element}</li>
)
}
})
}
}
export default TeamList
编码愉快!