You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React组件为何渲染两次?已用componentWillMount/DidMount求解决方案

React组件渲染两次的原因及解决办法

嘿,这其实是React的正常行为,完全不是bug哦!先给你拆解一下为什么会出现两次渲染:

为什么会渲染两次?

  • 第一次渲染:初始状态渲染
    组件挂载时,会先根据你在constructor里定义的初始state完成第一次渲染——这是React组件生命周期的必经环节,不管你有没有异步请求,它都会先把初始状态的内容渲染到页面上。

  • 第二次渲染:异步请求后的状态更新
    你用axios发起的是异步请求,它不会阻塞组件的挂载流程。当请求完成拿到数据后,你调用了setState更新状态,React检测到state发生变化,就会触发第二次重渲染,把最新的数据展示出来。

至于你尝试的componentWillMount和componentDidMount,不管把请求放在哪个钩子(注意现在componentWillMount已经被React官方不推荐使用了,更建议用componentDidMount),都改变不了异步请求的本质——初始渲染必然会先发生,因为请求需要时间,不可能在组件挂载瞬间就拿到数据。

怎么优化这个情况?

你不需要“阻止”第二次渲染(这是React响应式更新的核心,阻止反而会出问题),但可以通过添加加载状态来优化用户体验,避免初始状态的占位内容让用户困惑:

修改后的示例代码

export default class Dashboard extends Component{ 
  constructor(props) { 
    super(props) 
    this.state = { 
      data: {}, // 初始可以设为空,不需要占位内容
      loading: true // 新增加载状态,标记是否正在请求数据
    } 
  } 

  componentDidMount() { 
    // 用模板字符串拼接参数更简洁
    axios.get(`/api/data?param1=${this.props.location}`) 
      .then(response => {
        // 请求成功后更新数据,并把loading设为false
        this.setState({
          data: response.data,
          loading: false
        });
      })
      .catch(error => {
        // 别忘了处理错误,避免页面一直处于加载状态
        console.error('数据请求失败:', error);
        this.setState({ loading: false });
      });
  } 

  render() {
    const { loading, data } = this.state;

    // 如果还在加载,显示加载提示
    if (loading) {
      return <div>正在加载数据...</div>;
    }

    // 加载完成后,渲染真实数据
    return <div>{data.okay}</div>;
  }
}

额外说明

如果你强行想让组件只渲染一次,只能同步获取数据,但这会阻塞组件挂载,导致页面长时间空白,用户体验极差,完全不推荐这么做。React的设计就是通过状态变化驱动视图更新,两次渲染是合理且必要的——我们要做的是让这个过程对用户更友好,而不是违背React的设计逻辑。

内容的提问来源于stack exchange,提问作者psvs

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:16:10