用闭包实现带生命周期钩子的轻量级组件,核心是将状态与钩子函数封装在闭包中,暴露mount/update/unmount方法,支持异步清理与防错处理,无需class或this绑定。

用闭包实现带生命周期钩子的轻量级组件,核心是把状态和钩子函数封装在闭包作用域中,通过返回的对象暴露初始化、更新、销毁等方法,避免全局污染和类的开销。
封装生命周期状态与钩子函数
闭包内部维护一个状态对象(如 isMounted)和用户可注册的钩子函数(onInit、onUpdate、onDestroy),所有逻辑不依赖 this,也不需要 class 或 new。
示例结构:
- 闭包内定义私有状态(如
mounted = false、props = {}) - 提供
setHooks({ onInit, onUpdate, onDestroy })方法供外部注入行为 - 每个钩子只执行一次或按需触发,例如
onInit在首次mount()时调用
暴露标准组件接口:mount / update / unmount
返回一个对象,包含三个关键方法,它们共享闭包内的状态和钩子:
立即学习“Java免费学习笔记(深入)”;
分析 Java Spring Boot 后端 Controller 代码,自动生成 Markdown 格式的接口文档。当用户说“生成 Java 接口文档”、“生成 API 文档”、“从 Spring 代码生成文档”时触发。
-
mount(props):标记已挂载,合并 props,执行onInit(若存在) -
update(newProps):仅在已挂载时运行,触发onUpdate并更新内部 props -
unmount():置空状态、标记卸载,并调用onDestroy
这些方法天然“绑定”闭包上下文,无需 bind 或箭头函数绕过 this 问题。
支持异步钩子与清理逻辑
钩子函数可以返回清理函数(类似 React 的 effect cleanup),在下次 update 或 unmount 前自动执行:
- 内部维护一个
cleanup函数引用,每次onUpdate返回新函数时覆盖它 -
update()开始前先调用上一次的cleanup(如果存在) -
unmount()最后也执行当前cleanup,确保资源释放
这样就能自然支持定时器、事件监听、fetch 中止等常见场景。
使用示例:一个计数器组件
只需几行代码即可创建可复用、自带钩子的实例:
const createCounter = () => {
let count = 0;
let mounted = false;
let cleanup = () => {};
const hooks = {};
return {
setHooks: (h) => Object.assign(hooks, h),
mount: (initial = 0) => {
count = initial;
mounted = true;
hooks.onInit?.(count);
},
update: (delta) => {
if (!mounted) return;
cleanup();
count += delta;
cleanup = hooks.onUpdate?.(count) || (() => {});
},
unmount: () => {
cleanup();
mounted = false;
hooks.onDestroy?.();
}
};
};
// 使用
const counter = createCounter();
counter.setHooks({
onInit: (val) => console.log('init:', val),
onUpdate: (val) => {
console.log('update:', val);
const id = setInterval(() => {}, 1000);
return () => clearInterval(id); // 自动清理
},
onDestroy: () => console.log('destroyed')
});
counter.mount(10);
counter.update(5); // → init: 10, update: 15
counter.unmount(); // → destroyed + 清理定时器
不复杂但容易忽略:钩子执行顺序、清理时机、以及是否允许钩子抛错,都需要在闭包内部做简单防御(如 typeof hook === 'function' 判断)。

















