【问题标题】:Async makes render trigger before componentWillMount react?异步在 componentWillMount 反应之前触发渲染?
【发布时间】:2018-04-05 05:59:23
【问题描述】:
我想显示的下拉菜单有问题。我的主类调用下拉类,然后触发,componentWillMount() 然后开始提取,但是当提取获取其信息时,render() 开始并且我收到错误,因为信息仍然为空,因为尚未获取结果.任何人都知道如何用不同的方法解决这个问题。
export class Dropdown extends React.Component{
constructor() {
super();
this.state = {
info: null
}
}
componentWillMount() {
fetch("http://localhost:8081/getUsers")
.then(res => res.json())
.then(info => {
this.setState({info})
console.log(info['mta:getUsersResponse']['mta:users']);
})
}
render(){
const info = this.state.info;
console.log(info);
let menuItems = [];
for (var i = 0; i < info['mta:getUsersResponse']['mta:users'].length; i++) {
menuItems.push(<MenuItem eventKey="[i]">info['mta:getUsersResponse']['mta:users']['mta:FullName'][i]</MenuItem>);
}
return (
<DropdownButton bsStyle="primary" title="Users" key="dropdown1" id="1">
<MenuItem eventKey="1">Action</MenuItem>
{menuItems}
</DropdownButton>
);
}
}
【问题讨论】:
标签:
reactjs
components
render
async.js
【解决方案1】:
您检查 info 的值,如果它为 null,则返回 null,然后当状态更新时,它将返回 DropDown
例子
render() {
if (!this.state.info) return null;
const info = this.state.info;
console.log(info);
let menuItems = [];
for (var i = 0; i < info['mta:getUsersResponse']['mta:users'].length; i++) {
menuItems.push(<MenuItem eventKey="[i]">info['mta:getUsersResponse']['mta:users']['mta:FullName'][i]</MenuItem>);
}
return (
<DropdownButton bsStyle="primary" title="Users" key="dropdown1" id="1">
<MenuItem eventKey="1">Action</MenuItem>
{menuItems}
</DropdownButton>
);
}
【解决方案2】:
为了方便用户,您可以显示loading... 文本或动画图标而不是下拉菜单:
render() {
const { info } = this.state.info;
if (!info) return(
<div className="loader">Loading...</div>
)
// the code below will execute when `info` is not null.
let menuItems = [];
for (var i = 0; i < info['mta:getUsersResponse']['mta:users'].length; i++) {
menuItems.push(<MenuItem eventKey={i}>{info['mta:getUsersResponse']['mta:users'][i]['mta:FullName']}</MenuItem>);
}
return (
<DropdownButton bsStyle="primary" title="Users" key="dropdown1" id="1">
<MenuItem eventKey="1">Action</MenuItem>
{menuItems}
</DropdownButton>
);
}
但我认为无条件渲染DropdownButton 并填充成功响应选项会更好:
render() {
let MenuItems = []
const { info } = this.state.info
if (!info) {
MenuItems.push(<MenuItem>Loading...</MenuItem>)
}
else {
info['mta:getUsersResponse']['mta:users'].forEach((elem, i) => {
MenuItems.push(<MenuItem eventKey={i}>{elem['mta:FullName']}</MenuItem>)
})
}
return (
<DropdownButton bsStyle="primary" title="Users" key="dropdown1" id="1">
{menuItems}
</DropdownButton>
)
}