刚开始使用 react,很多属性、方法不是很熟。在此记录下我所遇到的问题及解决方法。

我在 componentWillMount() 中调用了一个异步函数,在返回结果中调用 this.setState() 来保存数据,在 render() 中使用 this.state.article 时,显示为 undefined。代码如下:

componentWillMount() {
  console.log('componentWillMount called')
  let _ = this
  // 获取当前文章 ID;
  let postID = utils.getID(ARTICLE)
 
  /**
   * @description 获取、渲染文章内容
   * @param {Number} postID - 当前文章 ID
   */
  postIO.getDetail(postID).then(res => {
    if (res.status === 200) {
      console.log('asynchronous called')
      let data = res.data
 
      _.setState({
        article: {...data},
              })
          }
  })
}
 
render() {
  console.log('render called')
  return (
    <div></div>
  )
}
 
可以看到控制台打印信息:
componentWillMount called
render called
asynchronous called
render called
 
这里可以得出:调用完 componentWillMount() 后,执行 render(),这时 componentWillMount 中的回调函数也执行完毕,更新数据后再次调用 render。
 
这个问题原因:首先,异步函数本身就是不会等前一个任务结束后再执行后一个函数,而是在执行其回调函数的同时就开始执行后一个函数了。因此,在调用完 componentWillMount 函数后,执行 postIO.getDetail(postID).then(res => {}),同时执行 render()。
 
可能导致的问题:在 componentWillMount 中的回调函数中调用 this.setState({article: {...data}}),第一次调用 render 时,是获取不到 this.state.article 的值的,这样就会引起报错。
 
解决方法:
增加一个加载状态,默认为 false,调用 componentWillMount() 时,设置为 true,当这个加载状态是 true 时,暂不渲染,当回调函数执行完毕后,设置为 false,此时再调用 render();
 
完整代码如下:
constructor(props) {
  super(props)
  
  this.state = {
    article: {},
    isLoading: false,
  }
}
componentWillMount() {
  let _ = this
  // 获取当前文章 ID;
  let postID = utils.getID(ARTICLE)
 
  _.setState({isLoading: true})
 
  /**
   * @description 获取、渲染文章内容
   * @param {Number} postID - 当前文章 ID
   */
  postIO.getDetail(postID).then(res => {
    if (res.status === 200) {
      console.log('asynchronous called')
      let data = res.data
 
      _.setState({
        article: {...data},
        isLoading: false
              })
          }
  })
}
 
render() {
  let {isLoading} = this.state
  if (isLoading) {
    return <p>isLoading...</p>
  }
  return (
    <div></div>
  )
}

react 在 componentWillMount() 中调用异步函数时,componentWillMount() finishes after render()的更多相关文章

  1. 关于在C#中构造函数中调用虚函数的问题

    在C#中如果存在类的继承关系,应避免在构造函数中调用虚函数.这是由于C#的运行机制造成的,原因如下: 新建一个类实例时,C#会先初始化该类(对类变量赋值,并将函数记在函数表中),然后再初始化父类.构造 ...

  2. Winform同步调用异步函数死锁原因分析、为什么要用异步

    1.前言 几年前,一个开发同学遇到同步调用异步函数出现死锁问题,导致UI界面假死.我解释了一堆,关于状态机.线程池.WindowsFormsSynchronizationContext.Post.co ...

  3. Lua中调用C函数

    Lua利用一个虚拟的堆栈来给C传递值或从C获取值.每当Lua调用C函数,都会获得一个新的堆栈,该堆栈初始包含所有的调用C函数所需要的参数值(Lua传给C函数的调用实参),并且C函数执行完毕后,会把返回 ...

  4. C中调用Lua函数

    我们先来看一个简单的例子: lua_State* L = NULL; // 内部调用lua函数 double f(double x, double y) { double z; lua_getglob ...

  5. C++箴言:避免构造或析构函数中调用虚函数

    如果你已经从另外一种语言如C#或者Java转向了C++,你会觉得,避免在类的构造函数或者析构函数中调用虚函数这一原则有点违背直觉.但是在C++中,违反这个原则会给你带来难以预料的后果和无尽的烦恼. 正 ...

  6. 读书笔记 effective c++ Item 9 绝不要在构造函数或者析构函数中调用虚函数

    关于构造函数的一个违反直觉的行为 我会以重复标题开始:你不应该在构造或者析构的过程中调用虚函数,因为这些调用的结果会和你想的不一样.如果你同时是一个java或者c#程序员,那么请着重注意这个条款,因为 ...

  7. 【校招面试 之 C/C++】第10题 C++不在构造函数和析构函数中调用虚函数

    1.不要在构造函数中调用虚函数的原因 在概念上,构造函数的工作是为对象进行初始化.在构造函数完成之前,被构造的对象被认为“未完全生成”.当创建某个派生类的对象时,如果在它的基类的构造函数中调用虚函数, ...

  8. Lua中调用C函数(lua-5.2.3)

    Lua能够调用C函数的能力将极大的提高Lua的可扩展性和可用性. 对于有些和操作系统相关的功能,或者是对效率要求较高的模块,我们全然能够通过C函数来实现,之后再通过Lua调用指定的C函数. 对于那些可 ...

  9. Effective C++ .09 不在构造和析构过程中调用virtual函数

    看过C++对象模型的话就可以知道,在构造基类时,完整的vtable没有建立起来(表项没有被相应的子类函数替换),因而无法调用到子类的函数(即构造函数中的virtual函数是本类里的方法,不是virtu ...

随机推荐

  1. try与except处理异常语句

    ji 简介 与其他语言相同,在python中,try/except语句主要是用于处理程序正常执行过程中出现的一些异常情况,如语法错(python作为脚本语言没有编译的环节,在执行过程中对语法进行检测, ...

  2. 『TensorFlow』读书笔记_VGGNet

    VGGNet网络介绍 VGG系列结构图, 『cs231n』卷积神经网络工程实践技巧_下 1,全部使用3*3的卷积核和2*2的池化核,通过不断加深网络结构来提升性能. 所有卷积层都是同样大小的filte ...

  3. HostPort和NodePort

    https://blog.51cto.com/12462495/2163239?source=dra

  4. vue实现tab切换功能

    最近用vue做一个页面的tab功能,经过一查找资料,没用路由,也没用动态组件,完美实现了tab切换功能,效果如下 下面是代码实现,这是模板 <article id="example&q ...

  5. Oracle 监听器日志配置与管理

    十一假期间,某客户因为监听日志问题导致系统登录挂起,当时在返京的路上,因客户业务不允许中断,无奈之下,借了个本子帮客户做了紧急处理,今天恰好有空,在网上搜了下有关监听日志的内容,发现一个不错的帖子,内 ...

  6. 7——ThinkPhp中的响应和重定向:

    public function index3(){ //响应数据: $data=['title'=>"标题部分","content"=>" ...

  7. java课堂笔记3

  8. 《JavaScript Dom 编程艺术》读书笔记-第8章

    充实文档的内容,包括几个方面: 一个为文档创建“缩略图列表”的函数: 一个为文档创建“文献来源链接”的函数: 一个为文档创建“快捷键清单”的函数. <abbr>在HTML5 中以取代< ...

  9. 微信连wifi,中文ssid报Invalid sign tosign错误

    Invalid sign tosign错误如上: 是微信官方接受和回传的问题,改固定字符解决: 比如将ssid固定修改为字符串‘ssid’即可:

  10. ArcGIS 按多边形区域统计栅格影像的一些信息

    在使用ArcGIS对栅格影像进行分析时,难免要进行一些统计类的分析.如统计框选区域的像素的个数,面积.均值等内容. 下面给出使用“Spatial Analyst Tools -- > Zonal ...