把 class 组件改函数组件,第一行就卡住:state 写哪、生命周期放哪?react hooks 的答案是一组 use 开头的函数,先吃透两个,大部分页面就能写了。

useState:函数组件的记忆

const [count, setCount] = useState(0); setCount(count + 1); setCount(prev => prev + 1);

同一个事件里连写两次 setCount(count + 1) 只会加一,因为 count 是本次渲染的旧值,要连续加就用函数式更新。存对象或数组时记得传新对象,直接改旧对象里的属性不会触发重新渲染,这是新手最常踩的坑。

useEffect:副作用的口子

useEffect(() => { document.title = '共' + count + '条'; }, [count]);

第二个参数是依赖数组:空数组只在挂载后跑一次,填 [count] 就是 count 变了才跑。发请求、订消息、改页面标题都放这里,清理工作写在它返回的那个函数里,比如清定时器、退订阅。依赖数组别撒谎,漏写依赖是最常见的 bug 来源,装 eslint-plugin-react-hooks 能自动提醒。

老项目怎么过渡

不用一次性重写。新组件直接函数组件加 hooks,老组件按需迁移。重复逻辑抽成 useXxx 开头的自定义 hook,分页、防抖、轮询都能封装进去复用。两条红线记牢:hook 只能在组件或自定义 hook 的顶层调用,不能塞进 if 和循环里;定时器回调里读 state 拿到的可能是旧值,用函数式更新或 useRef 绕开。

实际判断:新项目函数组件起步没悬念;维护多年的 class 大组件没必要追新硬改,改一个带出一串隐藏问题,值不当。