使用useOptimistic优雅实现状态预更新

useOptimistic

useOptimistic 是一个 React 钩子,能够让你在 React 中实现预更新功能。 触发这个钩子并不真正的修改 State 的内容,但是会刷新组件的UI

作用

optimistic 译为乐观,就是乐观的更新一个 state, 在一个异步操作中,我假定它的结果是好的,那我并不需要等待真正的结果返回,我就可以更新部分UI界面,以达到更好更快的交互和反馈体验。以往我们想要做这种操作是需要在失败时重置 state 的,略显麻烦, 且面临着更糟糕的性能问题,现在可以使用这个钩子实现

useOptimistic API 介绍

jsx 复制代码
const [optimisticState, addOptimistic] = useOptimistic(state, updateFn);

参数: state: 状态数据,一般传入 useState() 产生的 State, updateFn: 更新 useOptimistic 的内部 State 的函数, 这个函数接受两个参数, 一个是当前的State, 一个是用于更新当前 State 的数据, 并且返回一个新的 State。

返回结果: optimisticState: 当前更新由 addOptimistic 触发引起时(此时置于 pendding 状态),这个值就是 updateFn 的返回值,其他情况下与传入的 state 相同。 addOptimistic: 这是一个函数, 用于触发 optimisticState 的值, 传入的参数就是 updateFn 的第二个参数

使用场景

比如说一个帖子的点赞数,在用户点击点赞之后,我们并不需要真正的等待接口返回点赞成功才更新实时的点赞数, 我们可以在用户点击的时候马上就更新UI 点赞数+1, 然后后面再处理接口返回的结果就可以了。大致的代码如下。

javascript 复制代码
async function likePulsOne() {
  await new Promise((resolve) => setTimeout(resolve, 1000))
  return true
}

export default function App() {
  const [postState, setPostState] = useState({
    like: 1,
    //...
  });
  const [optimisticPostState, updateOptimisticPostState] = useOptimistic(
    postState,
    (state, newValue) => {
      return {
        ...state,
        like: state.like + 1
      }
    }
  );
  async function postLike() {
    const postPulsLike = await likePulsOne();

    setPostState((postState) => ({
      ...postState,
      like: postState.like + 1
    }));
  }
  return <div>
    <p>{ optimisticPostState.like } </p>
    <button onClick = {async val => {
      updateOptimisticPostState()
      await postLike()
    }}> like </button>
  </div>
}

上面的例子中, 因为我们默认是+1 所以并没有用到 newValue 值。

基本原理

触发 addOptimistic 更新 optimisticState 之后,React 会自动注册下一个更新任务,在下一个更新任务执行之前(经测试,应是触发 addOptimistic的当前函数出栈(调用栈)之后, 所以一般与 async 函数匹配使用,放在同步函数中,效果转瞬即逝。), 若你传入的State 有更新, 则使用新的 state, 若没有,则采用原来的State ,看上去就好像回退了一样。所以若更新失败了,并不需要手动执行回退的操作。

注意,这个是 React 19 的新功能。

完 (: 广州前端有好坑位喊我一声啊😓

相关推荐
放下华子我只抽RuiKe515 小时前
FastAPI 全栈后端(三):数据库与 ORM
前端·数据库·react.js·oracle·性能优化·前端框架·fastapi
oioihoii20 小时前
探索React与Microi吾码的完美结合:快速搭建项目,低代码便捷开发教程
react.js·低代码·rxjava
超哥--1 天前
B站视频内容智能分析系统(九):React 前端与管理面板
前端·react.js·前端框架
光影少年1 天前
懒加载与分包:React.lazy + Suspense
前端·react.js·掘金·金石计划
Aolith2 天前
React 路由守卫:我用一个组件替代了 Vue 的 beforeEach
前端·react.js
Maimai108082 天前
Web3 前端交易系统如何落地:从下单 UI 到 Operation 编码、签名与实时状态更新
前端·react.js·ui·架构·前端框架·web3
Cxiaomu2 天前
React接入WebRTC实时视频实践
react.js·音视频·webrtc
Maimai108082 天前
Web3 前端实时通信如何落地:从 SSE 订阅到行情、订单与账户状态更新
前端·javascript·react.js·前端框架·web3·状态模式
用户887665426632 天前
Web3 前端实时通信如何落地:从 SSE 订阅到行情、订单与账户状态更新
前端·react.js·web3