您的位置:首页 > Web前端 > React

react.js解决 render 比 componentWillMount 先执行完毕问题

2019-04-01 10:55 381 查看

react.js解决 render 比 componentWillMount 先执行完毕问题

componentWillMount异步调用导致函数未执行完毕,render()已渲染完毕,出现undefined参数

刚开始使用 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 (
    


  )
}

可以看到控制台打印信息:
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

isLoading…


  }
  return (
    
  )
}

PS.转载自 lee_xiumei(侵删)

https://www.cnblogs.com/lee-xiumei/p/8029298.html

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐