Fre.js Hooks 完全指南:深入理解 useState、useEffect 等核心API
Fre.js 是一个轻量级的 Concurrent UI 库,其 Hooks 系统为开发者提供了简洁而强大的状态管理和副作用处理能力。本文将带你全面掌握 Fre.js 中 useState、useEffect 等核心 Hooks 的使用方法,帮助你轻松构建高效的现代前端应用。
一、Fre.js Hooks 简介
Fre.js 的 Hooks 系统借鉴了 React Hooks 的设计理念,但针对自身轻量级特性进行了优化。通过 Hooks,你可以在函数组件中使用状态和其他 React 特性,而无需编写类组件。Fre.js 的 Hooks 实现位于 src/hook.ts 文件中,包含了一系列用于状态管理、副作用处理、性能优化等的钩子函数。
二、核心 Hooks 详解
2.1 useState:状态管理的基石
useState 是 Fre.js 中最基础也最常用的 Hook,它允许你在函数组件中添加状态。其基本用法如下:
const [state, setState] = useState(initialState);
从 src/hook.ts 的源码可以看出,useState 实际上是基于 useReducer 实现的:
export const useState = <T>(initState: T | (() => T)) => {
return useReducer<T, SetStateAction<T>>(null, initState)
}
这意味着 useState 本质上是 useReducer 的一种简化形式,适用于简单的状态管理场景。在实际应用中,你可以像这样使用 useState:
import { useState } from '../../src/index'
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
2.2 useEffect:处理副作用
useEffect 允许你在函数组件中执行副作用操作,如数据获取、订阅或手动修改 DOM。其基本用法如下:
useEffect(() => {
// 副作用操作
return () => {
// 清理函数
};
}, [dependencies]);
从 src/hook.ts 中可以看到,useEffect 的实现调用了 effectImpl 函数:
export const useEffect = (cb: EffectCallback, deps?: DependencyList) => {
return effectImpl(cb, deps!, 'effect')
}
effectImpl 函数会根据依赖数组的变化来决定是否执行副作用。当依赖数组发生变化时,useEffect 会先执行上一次的清理函数(如果有的话),然后再执行新的副作用函数。
下面是一个使用 useEffect 的实际例子,来自 demo/src/use-effect.tsx:
import { render, useState, useEffect, h } from '../../src'
function Example() {
const [count, setCount] = useState(0);
useEffect(() => {
document.title = `You clicked ${count} times`;
return () => {
// 清理函数,在组件卸载或依赖变化时执行
console.log('Cleanup function');
};
}, [count]); // 仅在 count 变化时执行
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
2.3 其他常用 Hooks
除了 useState 和 useEffect,Fre.js 还提供了其他常用的 Hooks:
- useReducer:用于处理复杂状态逻辑,比 useState 更适合管理包含多个子值的状态对象。
- useMemo:用于记忆计算结果,避免不必要的重复计算,提高性能。
- useCallback:用于记忆函数,避免不必要的函数重新创建。
- useRef:用于创建一个持久化的引用,可用于访问 DOM 元素或存储不需要触发重渲染的数据。
- useContext:用于在组件树中共享状态,避免 props drilling。
这些 Hooks 的实现都可以在 src/hook.ts 文件中找到。
三、Hooks 使用规则
使用 Fre.js Hooks 时,需要遵循以下规则:
- 只能在函数组件或自定义 Hook 的顶层调用 Hooks,不要在循环、条件或嵌套函数中调用。
- 只能在 Fre.js 函数组件或自定义 Hook 中调用 Hooks。
这些规则确保 Fre.js 能够正确地跟踪 Hooks 的调用顺序,从而正确地管理组件状态。
四、实际应用示例
下面是一个结合使用多个 Hooks 的示例,来自 demo/src/with-jotal.tsx:
import { useState, useEffect, render, h } from "../../src/index";
function TodoApp() {
const [todos, setTodos] = useState([]);
const [inputValue, setInputValue] = useState("");
useEffect(() => {
// 从本地存储加载 todos
const savedTodos = localStorage.getItem("todos");
if (savedTodos) {
setTodos(JSON.parse(savedTodos));
}
}, []);
useEffect(() => {
// 将 todos 保存到本地存储
localStorage.setItem("todos", JSON.stringify(todos));
}, [todos]);
const handleAddTodo = () => {
if (inputValue.trim()) {
setTodos([...todos, { text: inputValue, completed: false }]);
setInputValue("");
}
};
const handleToggleTodo = (index) => {
const newTodos = [...todos];
newTodos[index].completed = !newTodos[index].completed;
setTodos(newTodos);
};
return (
<div>
<input
type="text"
value={inputValue}
onChange={(e) => setInputValue(e.target.value)}
/>
<button onClick={handleAddTodo}>Add Todo</button>
<ul>
{todos.map((todo, index) => (
<li
key={index}
style={{ textDecoration: todo.completed ? "line-through" : "none" }}
onClick={() => handleToggleTodo(index)}
>
{todo.text}
</li>
))}
</ul>
</div>
);
}
render(<TodoApp />, document.getElementById("app"));
在这个示例中,我们使用了 useState 来管理 todos 和 inputValue 状态,使用了两个 useEffect 分别用于从本地存储加载数据和将数据保存到本地存储。
五、总结
Fre.js Hooks 为开发者提供了一种简洁、灵活的方式来管理组件状态和副作用。通过 useState、useEffect 等核心 Hooks,你可以编写出更加简洁、可维护的代码。无论是构建简单的 UI 组件还是复杂的应用,Fre.js Hooks 都能帮助你提高开发效率,改善代码质量。
如果你想深入了解 Fre.js Hooks 的实现细节,可以查看 src/hook.ts 文件。同时,demo/src 目录下的示例代码也是学习如何使用这些 Hooks 的好资源。
希望本文能够帮助你更好地理解和使用 Fre.js Hooks。开始使用 Fre.js Hooks,构建你的下一个精彩应用吧!
Kimi-K2.5Kimi K2.5 是一款开源的原生多模态智能体模型,它在 Kimi-K2-Base 的基础上,通过对约 15 万亿混合视觉和文本 tokens 进行持续预训练构建而成。该模型将视觉与语言理解、高级智能体能力、即时模式与思考模式,以及对话式与智能体范式无缝融合。Python00- QQwen3-Coder-Next2026年2月4日,正式发布的Qwen3-Coder-Next,一款专为编码智能体和本地开发场景设计的开源语言模型。Python00
xw-cli实现国产算力大模型零门槛部署,一键跑通 Qwen、GLM-4.7、Minimax-2.1、DeepSeek-OCR 等模型Go06
PaddleOCR-VL-1.5PaddleOCR-VL-1.5 是 PaddleOCR-VL 的新一代进阶模型,在 OmniDocBench v1.5 上实现了 94.5% 的全新 state-of-the-art 准确率。 为了严格评估模型在真实物理畸变下的鲁棒性——包括扫描伪影、倾斜、扭曲、屏幕拍摄和光照变化——我们提出了 Real5-OmniDocBench 基准测试集。实验结果表明,该增强模型在新构建的基准测试集上达到了 SOTA 性能。此外,我们通过整合印章识别和文本检测识别(text spotting)任务扩展了模型的能力,同时保持 0.9B 的超紧凑 VLM 规模,具备高效率特性。Python00
KuiklyUI基于KMP技术的高性能、全平台开发框架,具备统一代码库、极致易用性和动态灵活性。 Provide a high-performance, full-platform development framework with unified codebase, ultimate ease of use, and dynamic flexibility. 注意:本仓库为Github仓库镜像,PR或Issue请移步至Github发起,感谢支持!Kotlin08
VLOOKVLOOK™ 是优雅好用的 Typora/Markdown 主题包和增强插件。 VLOOK™ is an elegant and practical THEME PACKAGE × ENHANCEMENT PLUGIN for Typora/Markdown.Less00