乐于分享
好东西不私藏

从源码到架构:React useActionState 深度剖析

从源码到架构:React useActionState 深度剖析

React 19 引入的 useActionState 是近年来 React Hooks 体系中设计最精巧的 API 之一。它表面上只是一个管理表单状态的 Hook,但内部却隐藏着三 Hook 协作、循环队列调度、Transition 上下文恢复、Thenable 状态追踪等一系列精妙的工程实现。我们将从源码出发,逐层剥开它的架构设计,帮助我们真正理解这个 API 背后的设计哲学。


一、为什么 useActionState 值得深入分析?

在 React 19 之前,处理一个带有异步提交、loading 状态、错误处理的表单,我们需要这样写:

functionOldForm() {
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState(null);
const [result, setResult] = useState(null);

const handleSubmit = async (e) => {
    e.preventDefault();
    setIsLoading(true);
    setError(null);
try {
const formData = new FormData(e.target);
const res = await submitToServer(formData);
      setResult(res);
    } catch (err) {
      setError(err.message);
    } finally {
      setIsLoading(false);
    }
  };

return (
<formonSubmit={handleSubmit}>
<inputname="email" />
<buttondisabled={isLoading}>
        {isLoading ? '提交中...' : '提交'}
</button>
      {error && <pclassName="error">{error}</p>}
      {result && <pclassName="success">{result.message}</p>}
</form>

  );
}

三个 useState、一个 try/catch/finally、一个 e.preventDefault()——这是每一个 React 开发者都写过无数遍的样板代码。而 React 19 给出的答案是:

functionNewForm() {
const [state, formAction, isPending] = useActionState(
async (prevState, formData) => {
const res = await submitToServer(formData);
return { successtruemessage: res.message };
    },
    { successnullmessage'' }
  );

return (
<formaction={formAction}>
<inputname="email" />
<buttondisabled={isPending}>
        {isPending ? '提交中...' : '提交'}
</button>
      {state.message && (
<pclassName={state.success ? 'success: 'error'}>
          {state.message}
</p>
      )}
</form>

  );
}

一个 Hook,三个返回值,零样板代码。这不是简单的语法糖——它背后是一套完整的 Action 驱动状态管理架构。理解了 useActionState,我们就理解了 React 19 对"副作用即状态"这一理念的全部思考。


二、从 useFormState 到 useActionState

useActionState 的前身是 React Canary 版本中的 useFormState。React 团队在正式发布时将其重命名,这个决策背后蕴含着深刻的设计思考。

useFormState 的问题在于:它把自己框死了。 "Form" 这个词暗示它只能用于表单场景,但实际上这个 Hook 的能力远不止于此。任何需要"执行一个副作用,然后基于结果更新状态"的场景,都可以用它来处理。React 团队意识到了这个命名上的局限,做出了一个看似微小实则关键的决定——将其更名为 useActionState

这个改名反映了 React 19 的一个核心设计理念:Action 不只是表单的专利,它是一种通用的异步状态变更模式。 在 React 19 的语义体系中,"Action"指的是任何可能产生副作用并导致状态变更的函数调用。它可以是表单提交、按钮点击、数据同步,甚至是一个定时器触发的操作。useActionState 是这个 Action 体系的基础设施之一,与 useTransitionuseOptimisticuseFormStatus 共同构成了完整的 Action 工具链。

从 useFormState 到 useActionState 的演进,本质上是从"数据驱动"到"意图驱动"的范式转变。前者关注的是"表单有什么数据",后者关注的是"用户想做什么"。这种视角的转换,让 API 的抽象层级提升了一个维度。


三、API 表面:简洁之下的设计

3.1 函数签名

functionuseActionState<SP>(
  action: (state: Awaited<S>, payload: P) => Awaited<S> | Promise<Awaited<S>>,
  initialState: Awaited<S>,
  permalink?: string
): [Awaited<S>, (payload: P) => voidboolean]
;

这个签名中有几个值得注意的设计细节:

泛型 <S, P> 的双参数设计S 代表状态类型,P 代表 payload 类型。S 被 Awaited<> 包裹,意味着状态可以是 Promise<T> 类型——Action 返回的 Promise 会被自动解包。这个设计让同步和异步 Action 在类型层面保持统一。

**action 的第一个参数是 prevState**。这和 useReducer 的 reducer 函数签名一脉相承,但有一个关键区别:useReducer 的 reducer 是纯同步函数,而这里的 action 可以是异步函数。React 内部会自动处理 Promise 的解析和状态的更新。

permalink 参数。这是一个容易被忽略但设计精巧的参数。它用于 Server Components 场景,告诉 React 这个 Action 修改的是哪个页面的数据。在流式 SSR 中,React 会利用这个信息在服务端渲染时就展示 Action 的结果,而不需要等待客户端 hydration 完成。

3.2 三个返回值

const [state, dispatch, isPending] = useActionState(action, initialState);
返回值
类型
说明
stateAwaited<S>
Action 的最新执行结果,初始为 initialState
dispatch(payload: P) => void
触发 Action 的函数,payload 会作为第二个参数传给 action
isPendingboolean
是否有正在执行的 Action

isPending 的实现尤为巧妙。它不是简单的"Action 是否正在运行"标志,而是基于 React 的 Transition 机制实现的。当 Action 在 Transition 中执行时,isPending 会自动变为 true,在 Transition 完成后变为 false。这意味着它天然与 React 的并发渲染特性集成,能够在长时间运行的 Action 期间保持 UI 的响应性。


四、源码剖析:Hook 协作的秘密

这是本文最核心的部分。我们将深入 React 源码(packages/react-reconciler/src/ReactFiberHooks.js),看看 useActionState 到底是如何实现的。

4.1 整体架构

useActionState 的核心秘密在于:它不是一个 Hook,而是三个 Hook 的协作体

当我们在组件中调用 useActionState 时,React 内部会创建三个独立的 Hook 实例,它们各自管理不同的职责:

  • stateHook:存储 Action 的执行结果,本质上是 useState 的底层实现
  • pendingStateHook:追踪 pending 状态,使用 Thenable 模式实现细粒度的异步追踪
  • actionQueueHook:管理 Action 的执行队列,使用循环链表实现高效的入队和出队

4.2 mountActionState:初始化的精密工程

让我们看看首次渲染时的源码:

// packages/react-reconciler/src/ReactFiberHooks.js

// 一个恒等 reducer——直接返回新状态
functionactionStateReducer<S>(oldState: S, newState: S): S{
return newState;
}

functionmountActionState<SP>(
  action: (Awaited<S>, P
) => Awaited<S>,
initialStatePropAwaited<S>,
permalink?: string
): [Awaited<S>, (P) => voidboolean
{
// Hook 1: 状态 Hook —— 存储 Action 结果
const stateHook = mountStateImpl<Awaited<S>>(initialStateProp);
const setState = stateHook.queue.dispatch;

// Hook 2: Pending 状态 Hook —— 追踪异步执行状态
// 使用 Thenable 模式,类似 Transition 的 pending 追踪
const pendingStateHook = mountStateImpl<Thenable<boolean> | boolean>(false);
const setPendingState: boolean =>void =
    dispatchOptimisticSetState.bind(null, pendingStateHook.queue, false);

// Hook 3: Action 队列 Hook —— 管理执行队列
const actionQueueHook = mountRefImpl<ActionStateQueue<S, P> | null>(null);
const actionQueue = actionQueueHook.mutableRef;

// 初始化队列
if (actionQueue.current === null) {
    actionQueue.current = {
action: action,
state: initialStateProp,
pendingnull,  // 循环链表的头指针
    };
  }

// 创建 dispatch 函数
const dispatch = dispatchActionState.bind(
null,
    actionQueue.current,
    setState,
    setPendingState,
    action,
    permalink
  );

// 计算 isPending
const isPending =
    pendingStateHook.memoizedState !== false &&
    pendingStateHook.memoizedState !== null;

return [stateHook.memoizedState, dispatch, isPending];
}

这段代码有几个值得深入分析的细节:

actionStateReducer 是一个恒等函数。它直接返回 newState,不做任何计算。这意味着 useActionState 的状态更新不是通过 reducer 逻辑推导出来的,而是由 Action 函数直接决定的。这与 useReducer 形成了鲜明对比——useReducer 的状态是新状态由旧状态和 action type 推导而来,而 useActionState 的状态是 Action 函数的返回值。这个设计选择反映了两种不同的状态管理哲学。

**pendingStateHook 使用 dispatchOptimisticSetState**。这不是普通的 setState,而是 React 内部的乐观更新机制。当 Action 开始执行时,pending 状态会被设置为一个 Thenable 对象(一个具有 then 方法的对象),而不是简单的 true。React 的并发渲染器能够识别 Thenable 对象,并在其 resolve 时自动触发重新渲染。这种设计让 isPending 的更新与 React 的调度系统深度集成,而不是简单地设置一个布尔值。

**actionQueue 使用 mountRefImpl 而非 mountStateImpl**。这是一个关键的设计决策。队列的变更不应该触发重新渲染——只有队列中 Action 的执行结果才应该触发渲染。使用 Ref 来存储队列,确保了队列操作(入队、出队)不会导致不必要的渲染。

4.3 循环链表:Action 队列的数据结构

useActionState 的 Action 队列使用了一个循环单向链表(Circular Singly Linked List)来实现。这是一个在算法面试中经常出现的数据结构,React 团队将其应用到了实际的工程问题中。

// Action 队列节点的数据结构
interface ActionStateQueueNode<S, P> {
action(state: Awaited<S>, payload: P) => Awaited<S>;
  payload: P;
  nextState: Awaited<S> | null;  // Action 执行后的结果
  status: 'pending' | 'fulfilled' | 'rejected';
  value: Awaited<S> | null;
  then: Thenable<Awaited<S>>['then'] | null;
  next: ActionStateQueueNode<S, P> | null;  // 指向下一个节点
}

// Action 队列的数据结构
interface ActionStateQueue<S, P> {
action((state: Awaited<S>, payload: P) => Awaited<S>) | null;
  state: Awaited<S>;
  pending: ActionStateQueueNode<S, P> | null;  // 队列尾指针
}

为什么选择循环链表而不是数组或普通队列?有三个原因:

O(1) 的入队和出队操作。在循环链表中,入队只需要将新节点链接到尾节点的 next,并更新尾指针;出队只需要将尾节点的 next 指向第二个节点。不需要像数组那样进行元素移动或扩容。

天然的空队列判断。当队列中只有一个节点时,last.next === last,这个条件可以用来判断"这是最后一个 Action"。当队列为空时,pending === null

内存效率。不需要预先分配固定大小的数组,也不需要在队列增长时进行扩容复制。每个节点只在需要时创建,Action 完成后可以被垃圾回收。


五、dispatchActionState:触发 Action 的完整链路

当用户调用 dispatch(payload) 时,到底发生了什么?让我们追踪完整的执行链路。

5.1 dispatchActionState 源码

functiondispatchActionState<SP>(
  actionQueue: ActionStateQueue<S, P>,
  setState: (newState: Awaited<S>
) => void,
setPendingState: (isPending: boolean) => void,
action: (Awaited<S>, P) => Awaited<S>,
permalinkstring | undefined,
payloadP
{
// 1. 创建 Action 节点
const node: ActionStateQueueNode<S, P> = {
action: action,
payload: payload,
nextStatenull,
status'pending',
valuenull,
thennull,
nextnull,
  };

// 2. 加入循环队列(O(1) 操作)
const last = actionQueue.pending;
if (last === null) {
// 队列为空,自循环
    node.next = node;
  } else {
// 插入到尾部
    node.next = last.next;
    last.next = node;
  }
  actionQueue.pending = node;

// 3. 设置 pending 状态
  setPendingState(true);

// 4. 在 Transition 中执行 Action
  startTransition(() => {
    runActionStateAction(actionQueue, node);
  });
}

注意第 4 步:Action 总是在 startTransition 中执行。这确保了 Action 的状态更新被标记为低优先级的 Transition 更新,不会阻塞用户的高优先级交互(如输入、点击)。这是 React 19 "非阻塞 UI" 理念在 useActionState 中的具体体现。

5.2 runActionStateAction:执行引擎

functionrunActionStateAction<SP>(
  actionQueue: ActionStateQueue<S, P>,
  node: ActionStateQueueNode<S, P>
{
const action = node.action;
const payload = node.payload;
const prevState = actionQueue.state;

if (node.isTransition) {
// 恢复原始的 Transition 上下文
const prevTransition = ReactSharedInternals.T;
const currentTransition = ({}: any);
    ReactSharedInternals.T = currentTransition;

try {
const returnValue = action(prevState, payload);
const onStartTransitionFinish = ReactSharedInternals.S;
if (onStartTransitionFinish !== null) {
        onStartTransitionFinish(currentTransition, returnValue);
      }
      handleActionReturnValue(actionQueue, node, returnValue);
    } catch (error) {
      onActionError(actionQueue, node, error);
    } finally {
      ReactSharedInternals.T = prevTransition;
    }
  } else {
try {
const returnValue = action(prevState, payload);
      handleActionReturnValue(actionQueue, node, returnValue);
    } catch (error) {
      onActionError(actionQueue, node, error);
    }
  }
}

这段代码中最精妙的部分是 Transition 上下文的恢复。当 dispatch 在一个已有的 Transition 中被调用时(例如通过 <form action> 触发),React 会保存当前的 Transition 上下文(ReactSharedInternals.T),在 Action 执行时恢复它,执行完毕后再还原。这确保了嵌套 Transition 的正确性——内层 Action 能够感知到外层 Transition 的存在,从而正确处理 pending 状态和优先级。

ReactSharedInternals.T 和 ReactSharedInternals.S 是 React 内部的全局状态槽位,分别存储当前 Transition 实例和 Transition 完成回调。这些是 React 调度系统的核心内部 API,正常情况下开发者不应该直接访问它们。但在 useActionState 的实现中,React 团队需要操作这些底层 API 来确保 Action 执行与 Transition 系统的正确集成。


六、异步处理:Thenable 追踪

handleActionReturnValue 是 useActionState 处理异步 Action 的核心函数。它需要处理三种情况:同步值、Promise、Thenable。

functionhandleActionReturnValue<SP>(
  actionQueue: ActionStateQueue<S, P>,
  node: ActionStateQueueNode<S, P>,
  returnValue: Awaited<S> | Promise<Awaited<S>>
{
if (typeof returnValue === 'object' && returnValue !== null) {
if (typeof returnValue.then === 'function') {
// Promise 或 Thenable —— 异步处理
      returnValue.then(
(nextState: Awaited<S>) => onActionSuccess(actionQueue, node, nextState),
        (error: mixed) => onActionError(actionQueue, node, error)
      );
    } else {
// 同步对象值
const nextState = (returnValue: any);
      onActionSuccess(actionQueue, node, nextState);
    }
  } else {
// 同步原始值
const nextState = (returnValue: any);
    onActionSuccess(actionQueue, node, nextState);
  }
}

这里有一个容易忽略但极其重要的设计:**useActionState 检查的是 then 方法的存在,而不是 instanceof Promise**。这意味着它能够处理任何 Thenable 对象,不仅仅是原生 Promise。这个设计选择与 React 18 引入的 Thenable 概念一脉相承——React 的并发特性(如 Suspense、Transition)都基于 Thenable 协议而非 Promise API,因为 Thenable 是一个更通用的异步协议。

6.1 onActionSuccess:成功后的连锁反应

functiononActionSuccess<SP>(
  actionQueue: ActionStateQueue<S, P>,
  actionNode: ActionStateQueueNode<S, P>,
  nextState: Awaited<S>
{
// 1. 标记节点为已完成
  actionNode.status = 'fulfilled';
  actionNode.value = nextState;
  notifyActionListeners(actionNode);

// 2. 更新队列的状态快照
  actionQueue.state = nextState;

// 3. 从循环队列中出队,并执行下一个
const last = actionQueue.pending;
if (last !== null) {
const first = last.next;
if (first === last) {
// 这是队列中最后一个 Action
      actionQueue.pending = null;
    } else {
// 移除头节点,更新尾指针
const next = first.next;
      last.next = next;
// 递归执行下一个 Action
      runActionStateAction(actionQueue, next);
    }
  }
}

注意第 3 步的递归调用:当一个 Action 完成后,它会自动触发队列中的下一个 Action。这就是 useActionState 实现"顺序执行"的机制——即使我们快速点击了提交按钮三次,三个 Action 也会按照顺序依次执行,每个 Action 都能拿到前一个 Action 的执行结果作为 prevState

6.2 onActionError:错误的级联处理

functiononActionError<SP>(
  actionQueue: ActionStateQueue<S, P>,
  actionNode: ActionStateQueueNode<S, P>,
  error: mixed
{
  actionNode.status = 'rejected';
  actionNode.value = error;
  notifyActionListeners(actionNode);

// 关键:将 action 设为 null,阻止后续 Action 执行
  actionQueue.action = null;
  actionQueue.pending = null;

// 错误沿 Fiber 树向上传播
throw error;
}

当 Action 抛出异常时,onActionError 会将 actionQueue.action 设为 null。这个操作的效果是阻止队列中所有后续 Action 的执行。这是一种"快速失败"(fail-fast)策略——一旦某个 Action 失败,后续的 Action 即使已经入队也不会被执行,因为它们可能依赖于失败 Action 的结果。


七、updateActionState:更新时的 Hook 一致性

React 的 Hooks 系统要求 Hook 的调用顺序在每次渲染时保持一致。useActionState 在更新时的实现确保了这一点:

functionupdateActionState<SP>(
  action: (Awaited<S>, P
) => Awaited<S>,
initialStateAwaited<S>,
permalink?: string
): [Awaited<S>, (P) => voidboolean
{
// 按照挂载时的顺序恢复三个 Hook
const stateHook = updateWorkInProgressHook();
const pendingStateHook = updateWorkInProgressHook();
const actionQueueHook = updateWorkInProgressHook();

return updateActionStateImpl(
    stateHook, currentStateHook,
    pendingStateHook, currentPendingStateHook,
    actionQueueHook, currentActionQueueHook,
    action, initialState, permalink
  );
}

updateWorkInProgressHook() 是 React Hooks 系统的核心函数,它按照 Fiber 节点上 Hook 链表的顺序依次恢复每个 Hook 的状态。由于 mountActionState 按照固定顺序创建了三个 Hook(stateHook → pendingStateHook → actionQueueHook),updateActionState 必须以相同的顺序恢复它们。如果顺序不一致,React 会抛出"Hooks 顺序错误"的异常。

updateActionStateImpl 还会处理一个重要的边界情况:Action 函数的更新。如果组件重新渲染时传入了不同的 action 函数,updateActionStateImpl 会更新 actionQueue.action 的引用,确保后续的 dispatch 使用最新的 action 函数。这种"函数引用更新"的模式在 React 内部很常见,useEffect 和 useCallback 也采用了类似的策略。


八、架构全景:useActionState 在 React 19 生态中的位置

理解了 useActionState 的内部实现后,让我们把它放到 React 19 的整体架构中来看。

在这个架构图中,我们可以看到 useActionState 处于一个承上启下的关键位置:

向上,它为开发者提供了简洁的 API,隐藏了异步状态管理的复杂性。开发者只需要定义 Action 函数和初始状态,剩下的交给框架。

向下,它依赖 useTransition 的调度能力来管理更新的优先级,依赖 Reconciler 来处理新旧状态的差异,依赖 Committer 来将变更应用到 DOM。

横向,它与 useOptimistic 和 useFormStatus 形成互补。useOptimistic 负责在 Action 执行期间显示乐观的 UI 状态,useFormStatus 负责在表单子组件中访问父级表单的提交状态。三者配合使用,可以构建出完整的表单交互体验。

与 Server Actions 的集成是 useActionState 最重要的架构特性之一。当 Action 函数是一个 Server Action(通过 "use server" 指令标记的函数)时,useActionState 能够在服务端渲染阶段就执行 Action 并将结果包含在初始 HTML 中。这意味着用户在页面加载时就能看到 Action 的结果,而不需要等待客户端 JavaScript 加载和执行。这种"服务端优先"的策略是 React 19 全栈架构的核心优势。


九、举一反三:从源码推导行为

深入理解源码的最大价值在于:我们可以从实现推导出行为,而不是死记硬背 API 文档。 让我们用几个实际场景来验证这一点。

9.1 快速连续点击:队列的顺序保证

functionCounter() {
const [count, dispatch, isPending] = useActionState(
async (prev, delta) => {
awaitnewPromise(r => setTimeout(r, 1000));
return prev + delta;
    },
0
  );

return (
    <div>
      <p>Count: {count}</p>
      <p>Pending: {isPending ? 'yes' : 'no'}</
p>
      <button onClick={() => startTransition(() => dispatch(1))}>+1</button>
    </
div>
  );
}

快速点击两次 "+1",两次 dispatch 会被依次加入循环队列。第一个 Action 完成后(count 变为 1),第二个 Action 才开始执行(基于 prevState=1,结果为 2)。isPending 在整个过程中保持 true

这个行为完全可以从源码推导出来:dispatchActionState 将每个 dispatch 包装为一个 ActionNode 并加入循环队列,onActionSuccess 在当前 Action 完成后递归调用 runActionStateAction 执行下一个。队列的 FIFO 顺序保证了 Action 的执行顺序与 dispatch 的调用顺序一致。

9.2 错误传播:快速失败的连锁效应

functionForm() {
const [state, formAction, isPending] = useActionState(
async (prev, formData) => {
const name = formData.get('name');
if (!name) thrownewError('Name is required');
return { submittedtrue, name };
    },
    { submittedfalsename'' }
  );

return (
<ErrorBoundaryfallback={<p>Something went wrong</p>}>
<formaction={formAction}>
<inputname="name" />
<buttondisabled={isPending}>Submit</button>
</form>
</ErrorBoundary>

  );
}

当 Action 抛出异常时,onActionError 会将 actionQueue.action 设为 null,阻止后续排队的 Action 执行。错误会沿 Fiber 树向上传播,直到被最近的 Error Boundary 捕获。同时,isPending 会被重置为 false,确保 UI 不会永久卡在 loading 状态。

9.3 Transition 约束:为什么必须在 Transition 中调用?

如果直接调用 dispatch 而不包裹在 startTransition 中,且不通过 <form action> 传递,React 会抛出错误:

An async function with useActionState was called outside of a transition.

从源码可以理解这个约束的原因:isPending 的正确性依赖于 dispatchOptimisticSetState,而这个函数需要在 Transition 上下文中才能正确工作。没有 Transition 上下文,React 无法追踪 pending 状态的变化,也无法正确地将状态更新标记为低优先级。这不是一个任意的限制,而是架构上的必然要求。

9.4 与 useReducer 的对比:何时选择哪个?

维度
useReducer
useActionState
状态计算
纯同步 reducer
可以是异步函数
更新触发
dispatch({type: 'X'})dispatch(payload)
Pending 追踪
需要手动实现
内置 isPending
错误处理
在 reducer 中处理
自动传播到 Error Boundary
队列管理
无(每次 dispatch 立即执行)
内置顺序队列
适用场景
复杂的同步状态逻辑
异步 Action、表单提交、数据变更

一个实用的判断标准:如果我们的状态更新涉及 I/O 操作(网络请求、数据库写入、文件读写),使用 useActionState;如果只是纯计算逻辑,使用 useReducer


十、设计模式提炼:从 useActionState 学到的工程智慧

10.1 组合模式(Composition over Inheritance)

useActionState 没有实现一套全新的状态管理机制,而是组合了三个已有的基础 HookuseStateuseStateuseRef)来构建更高级的抽象。这种"用简单的积木搭建复杂的建筑"的思路,是 React Hooks 体系的核心设计原则。它告诉我们:好的 API 设计不是发明新的基础原语,而是在正确的抽象层级上组合已有的原语。

10.2 关注点分离(Separation of Concerns)

三个 Hook 各自管理一个独立的关注点:状态、pending 追踪、队列调度。它们通过闭包和引用相互通信,但各自的生命周期是独立的。这种分离使得每个部分都可以独立测试和优化,也使得整个系统的复杂度被控制在可管理的范围内。

10.3 Thenable 协议优于 Promise API

useActionState 检查 then 方法而非 instanceof Promise,这个设计选择体现了"协议优于实现"的工程原则。Thenable 是一个更轻量的协议,任何实现了 then 方法的对象都可以参与 React 的异步系统,不需要依赖特定的 Promise 实现。这种设计在 React 的 Suspense、Transition 等特性中一以贯之。

10.4 快速失败与优雅降级

onActionError 中的"清空队列"策略是一种快速失败模式。在分布式系统和并发编程中,快速失败是一种重要的设计原则——当检测到不可恢复的错误时,立即停止所有后续操作,而不是让错误在系统中级联传播。useActionState 将这个原则应用到了前端状态管理中。


十一、总结:从实现细节到设计哲学

回顾 useActionState 的完整实现,我们可以看到四个层次的设计智慧:

第一层:API 设计的简洁性。 三个返回值 [state, dispatch, isPending] 覆盖了 Action 驱动状态变更的所有需求,没有多余的配置项,没有复杂的选项对象。好的 API 就像好的数学公式——简洁,但蕴含丰富的信息。

第二层:数据结构的精巧性。 循环链表实现 O(1) 的队列操作,Thenable 模式实现细粒度的异步追踪,ActionNode 的状态机设计确保了生命周期的清晰可控。这些数据结构的选择不是随意的,而是针对具体问题的最优解。

第三层:架构集成的一致性。useActionState 不是孤立存在的——它与 useTransition 共享底层机制,与 Server Components 无缝集成,与 <form action> 形成完整的表单解决方案。这种"在正确的抽象层级上保持一致性"的设计,是框架级 API 和库级 API 的本质区别。

第四层:设计哲学的前瞻性。 从 useFormState 到 useActionState 的改名,从"数据驱动"到"意图驱动"的范式转变,React 团队正在构建一个以 Action 为核心的声明式副作用体系。useActionState 是这个体系的关键拼图——它不仅仅是一个表单 Hook,而是 React 对"如何在 UI 框架中优雅地处理副作用"这个根本性问题的回答。

作为工程师,从优秀的框架源码中学习的不仅仅是实现技巧,更是如何在简洁性和表达力之间找到平衡,如何在性能和正确性之间做出取舍,如何设计出既能解决当下问题又能适应未来演进的抽象。这些才是真正值得反复品味的设计智慧。


本文基于 React 19 源码(packages/react-reconciler/src/ReactFiberHooks.js)分析,涉及的内部 API 可能随版本更新而变化。建议结合 React GitHub 仓库的最新代码对照阅读。

基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-05-11 12:25:22 HTTP/1.1 GET : https://www.yeyulingfeng.com/a/603471.html
  2. 运行时间 : 0.123733s [ 吞吐率:8.08req/s ] 内存消耗:4,696.09kb 文件加载:145
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=1de7f27782adf3f1f6f45dcb4106ddb4
  1. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/public/index.php ( 0.79 KB )
  2. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/autoload.php ( 0.17 KB )
  3. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/composer/autoload_real.php ( 2.49 KB )
  4. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/composer/platform_check.php ( 0.90 KB )
  5. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/composer/ClassLoader.php ( 14.03 KB )
  6. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/composer/autoload_static.php ( 6.05 KB )
  7. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/helper.php ( 8.34 KB )
  8. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-validate/src/helper.php ( 2.19 KB )
  9. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/ralouphie/getallheaders/src/getallheaders.php ( 1.60 KB )
  10. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/helper.php ( 1.47 KB )
  11. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/stubs/load_stubs.php ( 0.16 KB )
  12. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Exception.php ( 1.69 KB )
  13. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-container/src/Facade.php ( 2.71 KB )
  14. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/deprecation-contracts/function.php ( 0.99 KB )
  15. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/polyfill-mbstring/bootstrap.php ( 8.26 KB )
  16. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/polyfill-mbstring/bootstrap80.php ( 9.78 KB )
  17. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/var-dumper/Resources/functions/dump.php ( 1.49 KB )
  18. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-dumper/src/helper.php ( 0.18 KB )
  19. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/var-dumper/VarDumper.php ( 4.30 KB )
  20. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/guzzlehttp/guzzle/src/functions_include.php ( 0.16 KB )
  21. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/guzzlehttp/guzzle/src/functions.php ( 5.54 KB )
  22. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/App.php ( 15.30 KB )
  23. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-container/src/Container.php ( 15.76 KB )
  24. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/psr/container/src/ContainerInterface.php ( 1.02 KB )
  25. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/provider.php ( 0.19 KB )
  26. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Http.php ( 6.04 KB )
  27. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/helper/Str.php ( 7.29 KB )
  28. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Env.php ( 4.68 KB )
  29. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/common.php ( 0.03 KB )
  30. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/helper.php ( 18.78 KB )
  31. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Config.php ( 5.54 KB )
  32. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/alipay.php ( 3.59 KB )
  33. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/facade/Env.php ( 1.67 KB )
  34. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/app.php ( 0.95 KB )
  35. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/cache.php ( 0.78 KB )
  36. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/console.php ( 0.23 KB )
  37. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/cookie.php ( 0.56 KB )
  38. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/database.php ( 2.48 KB )
  39. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/filesystem.php ( 0.61 KB )
  40. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/lang.php ( 0.91 KB )
  41. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/log.php ( 1.35 KB )
  42. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/middleware.php ( 0.19 KB )
  43. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/route.php ( 1.89 KB )
  44. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/session.php ( 0.57 KB )
  45. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/trace.php ( 0.34 KB )
  46. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/view.php ( 0.82 KB )
  47. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/event.php ( 0.25 KB )
  48. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Event.php ( 7.67 KB )
  49. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/service.php ( 0.13 KB )
  50. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/AppService.php ( 0.26 KB )
  51. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Service.php ( 1.64 KB )
  52. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Lang.php ( 7.35 KB )
  53. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/lang/zh-cn.php ( 13.70 KB )
  54. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/initializer/Error.php ( 3.31 KB )
  55. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/initializer/RegisterService.php ( 1.33 KB )
  56. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/services.php ( 0.14 KB )
  57. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/service/PaginatorService.php ( 1.52 KB )
  58. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/service/ValidateService.php ( 0.99 KB )
  59. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/service/ModelService.php ( 2.04 KB )
  60. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-trace/src/Service.php ( 0.77 KB )
  61. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Middleware.php ( 6.72 KB )
  62. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/initializer/BootService.php ( 0.77 KB )
  63. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/Paginator.php ( 11.86 KB )
  64. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-validate/src/Validate.php ( 63.20 KB )
  65. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/Model.php ( 23.55 KB )
  66. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/Attribute.php ( 21.05 KB )
  67. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/AutoWriteData.php ( 4.21 KB )
  68. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/Conversion.php ( 6.44 KB )
  69. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/DbConnect.php ( 5.16 KB )
  70. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/ModelEvent.php ( 2.33 KB )
  71. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/RelationShip.php ( 28.29 KB )
  72. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/contract/Arrayable.php ( 0.09 KB )
  73. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/contract/Jsonable.php ( 0.13 KB )
  74. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/contract/Modelable.php ( 0.09 KB )
  75. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Db.php ( 2.88 KB )
  76. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/DbManager.php ( 8.52 KB )
  77. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Log.php ( 6.28 KB )
  78. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Manager.php ( 3.92 KB )
  79. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/psr/log/src/LoggerTrait.php ( 2.69 KB )
  80. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/psr/log/src/LoggerInterface.php ( 2.71 KB )
  81. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Cache.php ( 4.92 KB )
  82. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/psr/simple-cache/src/CacheInterface.php ( 4.71 KB )
  83. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/helper/Arr.php ( 16.63 KB )
  84. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/cache/driver/File.php ( 7.84 KB )
  85. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/cache/Driver.php ( 9.03 KB )
  86. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/contract/CacheHandlerInterface.php ( 1.99 KB )
  87. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/Request.php ( 0.09 KB )
  88. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Request.php ( 55.78 KB )
  89. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/middleware.php ( 0.25 KB )
  90. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Pipeline.php ( 2.61 KB )
  91. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-trace/src/TraceDebug.php ( 3.40 KB )
  92. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/middleware/SessionInit.php ( 1.94 KB )
  93. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Session.php ( 1.80 KB )
  94. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/session/driver/File.php ( 6.27 KB )
  95. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/contract/SessionHandlerInterface.php ( 0.87 KB )
  96. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/session/Store.php ( 7.12 KB )
  97. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Route.php ( 23.73 KB )
  98. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/RuleName.php ( 5.75 KB )
  99. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/Domain.php ( 2.53 KB )
  100. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/RuleGroup.php ( 22.43 KB )
  101. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/Rule.php ( 26.95 KB )
  102. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/RuleItem.php ( 9.78 KB )
  103. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/route/app.php ( 3.94 KB )
  104. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/facade/Route.php ( 4.70 KB )
  105. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/dispatch/Controller.php ( 4.74 KB )
  106. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/Dispatch.php ( 10.44 KB )
  107. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/controller/Index.php ( 9.87 KB )
  108. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/BaseController.php ( 2.05 KB )
  109. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/facade/Db.php ( 0.93 KB )
  110. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/connector/Mysql.php ( 5.44 KB )
  111. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/PDOConnection.php ( 52.47 KB )
  112. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/Connection.php ( 8.39 KB )
  113. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/ConnectionInterface.php ( 4.57 KB )
  114. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/builder/Mysql.php ( 16.58 KB )
  115. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/Builder.php ( 24.06 KB )
  116. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/BaseBuilder.php ( 27.50 KB )
  117. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/Query.php ( 15.71 KB )
  118. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/BaseQuery.php ( 45.13 KB )
  119. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/TimeFieldQuery.php ( 7.43 KB )
  120. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/AggregateQuery.php ( 3.26 KB )
  121. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/ModelRelationQuery.php ( 20.07 KB )
  122. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/ParamsBind.php ( 3.66 KB )
  123. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/ResultOperation.php ( 7.01 KB )
  124. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/WhereQuery.php ( 19.37 KB )
  125. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/JoinAndViewQuery.php ( 7.11 KB )
  126. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/TableFieldInfo.php ( 2.63 KB )
  127. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/Transaction.php ( 2.77 KB )
  128. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/log/driver/File.php ( 5.96 KB )
  129. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/contract/LogHandlerInterface.php ( 0.86 KB )
  130. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/log/Channel.php ( 3.89 KB )
  131. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/event/LogRecord.php ( 1.02 KB )
  132. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/Collection.php ( 16.47 KB )
  133. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/facade/View.php ( 1.70 KB )
  134. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/View.php ( 4.39 KB )
  135. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/controller/Es.php ( 3.30 KB )
  136. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Response.php ( 8.81 KB )
  137. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/response/View.php ( 3.29 KB )
  138. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Cookie.php ( 6.06 KB )
  139. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-view/src/Think.php ( 8.38 KB )
  140. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/contract/TemplateHandlerInterface.php ( 1.60 KB )
  141. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-template/src/Template.php ( 46.61 KB )
  142. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-template/src/template/driver/File.php ( 2.41 KB )
  143. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-template/src/template/contract/DriverInterface.php ( 0.86 KB )
  144. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/runtime/temp/c935550e3e8a3a4c27dd94e439343fdf.php ( 31.50 KB )
  145. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-trace/src/Html.php ( 4.42 KB )
  1. CONNECT:[ UseTime:0.000561s ] mysql:host=127.0.0.1;port=3306;dbname=wenku;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.000805s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.000349s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.000319s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.000881s ]
  6. SELECT * FROM `set` [ RunTime:0.000252s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.000655s ]
  8. SELECT * FROM `article` WHERE `id` = 603471 LIMIT 1 [ RunTime:0.000571s ]
  9. UPDATE `article` SET `lasttime` = 1778473522 WHERE `id` = 603471 [ RunTime:0.019736s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 64 LIMIT 1 [ RunTime:0.000352s ]
  11. SELECT * FROM `article` WHERE `id` < 603471 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.000672s ]
  12. SELECT * FROM `article` WHERE `id` > 603471 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.000486s ]
  13. SELECT * FROM `article` WHERE `id` < 603471 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.001793s ]
  14. SELECT * FROM `article` WHERE `id` < 603471 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.004126s ]
  15. SELECT * FROM `article` WHERE `id` < 603471 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.006221s ]
0.126114s