我正在尝试使用promise填充反应组件。我已调试,this.setState({items: items})
内的componentWillMount()
语句在render()
之后调用,因此render函数中的items数组总是为空。我也尝试使用componentDidMount()
。
这是正确的方法吗?
interface Props extends React.Props<ItemsListComponent> {
isAddButtonClicked : boolean;
newItem : string;
}
interface State {
items : Array<ItemEntity>;
}
export class ItemsListComponent extends React.Component<Props, State> {
constructor(props: Props) {
super(props);
this.state = {items: []};
}
public componentWillMount() {
itemAPI.getAllItems().then((items) => {
this.setState({items: items})
});
}
render() {
return(
<div className="container">
<div className="row">
<ul className="list-group">
{this.state.items.map((item : ItemEntity) =>
// Each child in an array or iterator should have a unique "key" prop. React doc.
<li className="list-group-item" key={item.id}>{item.task}</li>
)}
</ul>
</div>
</div>
);
}
}
答案 0 :(得分:2)
问题是当React呈现组件时数据尚不可用。在实践中,您的代码应该在组件或更高版本上防止这种情况:
render() {
if(!this.state.items) return null; // or loading indicator, data has not returned yet
return (<div className="container">
...
</div>);
}
答案 1 :(得分:0)
我会将itemAPI.getAllItems()
放在组件的构造函数中。一旦项目到达,无论何时,状态都将更新,这将触发render()
。
答案 2 :(得分:0)
创建方法&#39; asyncUpdate(data){this.setState(data)}&#39; 在构造函数集中 &#39; this.asyncUpdate = this.asyncUpdate.bind(this)&#39;
在你的承诺之后调用触发器&quot; this.asyncUpdate(promisedData)&#39;
应该帮助
答案 3 :(得分:0)
来自文档:componentWillMount() is invoked immediately before mounting occurs. It is called before render(), therefore setting state synchronously in this method will not trigger a re-rendering. Avoid introducing any side-effects or subscriptions in this method.
您应该能够在componentDidMount()中提出请求。这确保了状态改变时的重新渲染。如果它仍然为空,则渲染中的地图有可能返回一个空数组。确保正确格式化从api返回的项目。答案的形式可能是{ items: [] }.
答案 4 :(得分:0)
根据React Documentation调用API最好在componentDidMount()中完成。
结合Benjamin的答案,将为您提供最佳实施。