react 19 新hook,useActionState,你了解如何使用么?你回答了解了。那么你会自己实现么?你可能不会!

react 19版本 正式推出没有多久,新的特性也非常多,比如

  1. 渲染性能提升,
  2. 新的hook
  3. 对服务端组件的支持更加好等等。。。

废话不多说,这篇文章不是介绍它们如何使用的,官方链接(react.dev/reference/r...)

正如标题所说的,你可能比任何人都提前知道了新的hook的使用以及使用场景。但不知道你有没有尝试从0-1实现一下新的hook,探究一下它可能的实现原理 或者 有没有可能设计一个更加符合自己实际业务场景的。

useActionState

在 React 19 中,新的 useActionState 钩子简化了异步操作的处理方式,提升了可用性和性能。以下是useActionState 的一个基本实现概要:

1. 钩子定义

useActionState 钩子旨在管理异步操作的状态,包括错误处理和待处理状态。它支持乐观更新并与表单提交无缝集成。

2. 状态管理

使用 React 的 useState 来跟踪 error(错误)和 isPending(待处理)状态。

3. 函数组合

钩子接受一个异步操作函数,并管理其执行和结果。

4. 返回值

返回 errorsubmitAction 函数和 isPending 状态。

还返回 currentState, upateCurrentState, previousStateRef (这个与官方设计不一样)

实现示例

以下是一个基于描述的 useActionState 钩子的基本实现示例:

js 复制代码
import { useState, useCallback, useRef } from 'react';

function useActionState(action, initialError = null, initialState = null) {
  const [error, setError] = useState(initialError);
  const [isPending, setIsPending] = useState(false);
  
  // 使用 useRef 存储前一个状态
  const previousStateRef = useRef(initialState);
  
  const [currentState, setCurrentState] = useState(initialState);

  const submitAction = useCallback(
    async (...args) => {
      setIsPending(true);
      setError(initialError);
      try {
        // 传递 previousStateRef.current 作为前一个状态
        const result = await action(previousStateRef.current, ...args);
        if (result) {
          setError(result); // 如果有错误,设置错误状态
        } else {
          // 假设 action 成功后会更新 currentState
          // 例如,action 可以返回新的状态值
          // 这里假设 action 内部已经处理了 state 的更新
        }
      } catch (err) {
        setError(err.message || '发生了意外错误');
      } finally {
        setIsPending(false);
      }
    },
    [action, initialError]
  );

  // 更新当前状态并同步更新 previousStateRef
  const updateCurrentState = useCallback(
    (newState) => {
      previousStateRef.current = currentState; // 先将 currentState 赋值给 previousStateRef
      setCurrentState(newState); // 然后更新 currentState
    },
    [currentState]
  );

  return [error, submitAction, isPending, currentState, updateCurrentState, previousStateRef];
}

export default useActionState;

步骤解析:

  1. 初始化状态

    • error:初始错误状态(默认为 null)。
    • isPending:表示异步操作是否在进行中。
    • currentStatepreviousStateRef:用于管理当前和前一个状态。
  2. submitAction 函数

    • 设置 isPendingtrue,并重置错误状态。

    • 调用 action 函数,并传递 previousStateRef.current 作为前一个状态。

    • 根据 action 的返回值:

      • 如果 result 为真值,表示有错误,调用 setError(result)
      • 如果 result 为假值,表示操作成功,可能会通过 updateCurrentState 更新 currentState
    • 捕获异常并设置错误状态。

    • 最后,将 isPending 设置回 false

  3. updateCurrentState 函数

    • 更新 previousStateRef.current 为当前的 currentState
    • 更新 currentState 为新的状态值。

这篇我们尝试实现了一个useActionState,以及讲解了它可能的实现原理, 以及如何根据实际使用场景定制一个符合自己的版本。

如果文章对你有帮助,请点个赞支持一下!

啥也不是,散会。

相关推荐
AlienZHOU4 小时前
AI Coding 时代下,我的技术面试实践分享
前端·后端·面试
Captaincc7 小时前
AI用量v0.1.11更新发布 新增 jusage doctor 诊断指令 托盘展示token 和余额 新增 AutoClaw 支持
前端·后端·vibecoding
计算机魔术师9 小时前
德国Wiki被黑后两周,OpenAI终于把模型失控的账本摊开了
前端
kyriewen9 小时前
我让 AI 当面试官面了我一轮:第 3 个追问我就卡住了(附 10 道追问清单)
前端·面试·ai编程
IT_陈寒9 小时前
Python的GIL把我坑惨了,多线程跑得比单线程还慢
前端·人工智能·后端
前端snow10 小时前
ai agent --- 多agent框架之图编排引擎-langgraph
前端
竹林81810 小时前
OmniPic Studio v3.2.1 核心技术架构与全平台发版解析文档
前端·浏览器
JamesZhang8007810 小时前
页面内存只涨不跌? 一次泄漏排查, 牵出 WeakMap 的诞生
前端
Z小明10 小时前
第 6 章 组件进阶
前端·vue.js
江华森10 小时前
HTTP请求的完整过程详解:从DNS解析到TCP挥手的微秒级实战分析
前端