【问题标题】: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>
  );
    }
}

【问题讨论】:

  • 在正确获取数据之前不能只渲染 null 吗?

标签: 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>
      )
    }
    

    【讨论】:

      猜你喜欢
      • 2018-04-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-09
      • 1970-01-01
      • 2016-09-12
      • 2020-12-21
      • 2020-11-20
      相关资源
      最近更新 更多