异步在 componentWillMount 反应之前使渲染触发?

Async makes render trigger before componentWillMount react?

我要显示的下拉菜单有问题。我的主要 class 调用下拉菜单 class 然后触发, 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>
  );
    }
}

您检查 info 的值,如果它为 null,则 return null 然后当状态更新时,它将 return 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>
  );
}

为了方便用户使用,您可以显示 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>
  )
}