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

本文介绍在React中如何解决因componentWillMount中异步数据加载导致的初次渲染时state值未准备好问题。通过引入加载状态标识,确保数据加载完成后再进行页面渲染,避免undefined错误。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值