在componentWillMount做出反应之前,异步会使渲染触发吗?

时间:2017-10-24 12:22:28

标签: reactjs components render async.js

我想要显示下拉列表的问题。我的主类调用dropdown类然后触发,componentWillMount()然后启动fetch但是当fetch获取其信息时render()启动并且我得到错误因为info仍然为null,因为结果还没有被提取。任何人都知道如何解决这个问题,用不同的方法撕开我的头发。

    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>
  );
    }
}

2 个答案:

答案 0 :(得分:0)

检查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>
  );
}

答案 1 :(得分:0)

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