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

React组件初始渲染时为何出现卸载后重新挂载的异常?

为什么React组件初始渲染阶段会出现卸载操作?

相关组件代码

App 组件

function App() {
  return (
    <div className="App">
        <FunctionalComp />
        <ClassComp />
    </div>
  );
}

函数组件(FunctionalComp)

import React, { useEffect, useState } from 'react'

const FunctionalComp = ({intial}) => {
    const [count,setCount]=useState(intial);
    useEffect(()=>{
        if(count!==intial){
            console.log('Functional Component did Update');
        }
    },[count])
    useEffect(()=>{
        console.log('Functional component mounted');
    },[])
    useEffect(()=>{
        return ()=>{
            console.log('Functional Component Will unmout');
        }
    })
  return (
    <div>
        <h1>FunctionalComp</h1>
        <h4>{count?count:0}</h4>
        <button onClick={()=>{setCount(count+1)}}>Count</button>
    </div>
  )
}

export default FunctionalComp

类组件(ClassComp)

import React, { Component } from 'react'

export default class ClassComp extends Component {
    constructor(){
        super()
        this.state={
            count:0
        }
    }
    componentDidMount(){
        console.log('class Component did Mount ');
    }
    componentDidUpdate(){
        console.log('Class component did update');
    }
    componentWillUnmount(){
        console.log('Class component will unmount');
    }
  render() {
    return (
        <div>
            <h1>Class Component</h1>
            <h4>{this.state.count}</h4>
            <button onClick={()=>{this.setState({count:this.count+1})}}>count</button>
        </div>
    )
  }
}

实际控制台输出

class Component did Mount
Functional component mounted
Class component will unmount
Functional Component Will unmout
class Component did Mount
Functional component mounted

预期控制台输出

class Component did Mount
Functional component mounted
class Component did Mount
Functional component mounted


问题原因及解决办法

  1. React严格模式的开发环境特性
    你大概率是在开发环境下运行代码,React的Strict Mode(严格模式)会刻意重复执行组件的挂载、卸载逻辑,目的是帮你检测那些没有正确清理的副作用。这是开发环境的调试机制,生产环境不会出现这种重复挂载卸载的情况。

  2. 未指定依赖数组的useEffect
    你的FunctionalComp里第三个useEffect没有设置依赖数组,这意味着它会在每次组件渲染时先执行上一次的清理函数(也就是打印卸载日志的return函数),再执行当前的effect。结合严格模式的重复渲染,就出现了初始阶段的卸载日志。

修复方案

  • 如果你是想模拟组件真正卸载时的清理操作,给这个useEffect加上空依赖数组[],这样清理函数只会在组件被真正卸载时执行:
    useEffect(()=>{
        return ()=>{
            console.log('Functional Component Will unmout');
        }
    }, []) // 添加空依赖数组
    
  • 如果你只是想临时关闭这个调试行为,可以移除App组件外层的<React.StrictMode>标签,但不推荐这么做——严格模式能帮你提前发现很多潜在的副作用问题。

另外提个小问题:ClassComp里的按钮点击逻辑写错了,this.setState({count:this.count+1})应该改成this.setState({count: this.state.count + 1}),不然点击按钮不会正确更新count值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 12:53:18