首页
/ Fre.js Hooks 完全指南:深入理解 useState、useEffect 等核心API

Fre.js Hooks 完全指南:深入理解 useState、useEffect 等核心API

2026-02-04 05:00:23作者:吴年前Myrtle

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 时,需要遵循以下规则:

  1. 只能在函数组件或自定义 Hook 的顶层调用 Hooks,不要在循环、条件或嵌套函数中调用。
  2. 只能在 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,构建你的下一个精彩应用吧!

登录后查看全文
热门项目推荐
相关项目推荐