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
相关产品推荐
相关产品推荐

