likes
comments
collection
share

【译】介绍 Legend-State 1.0:更快地构建应用程序

作者站长头像
站长
· 阅读数 42

原文Introducing Legend-State 1.0: Build faster apps faster由幕呈翻译

经过将近一年的开发和迭代,我们非常高兴地宣布,Legend-State 已经达到了 1.0 版本!起初,它只是 Legend 状态/同步系统的一个简单升级,然后与 Bravely 进行了合作,进而追求最佳性能,最后彻底重新思考了 React 的开发体验(DX)。

因此,在 1.0 版本中,Legend-State 具有四个主要优点:

  • ⚡️ 最快的 React 状态库
  • 🦄 非常易于使用
  • 🔥 自然的细粒度响应性
  • 💾 内置持久性

在使用 Legend-State 构建三个大型应用程序(Legend 的 React 应用程序以及 Bravely 的 React 和 React Native 应用程序)时,我们有足够的空间来迭代实现最佳 DX,并在各种场景中优化性能。现在,它们已经发布并在生产环境中运行,我们相信 Legend-State 已经准备好让您构建应用程序了。

👋 介绍 Legend-State

Legend-State 是一个基于 Observables 的超快速和强大的 React 状态库。你可能最近听说过很多关于 Signals 的事情 - Observables 在概念上类似,但更强大:它们是深度响应的对象,当其中任何内容发生变化时,会通知监听器。

由于我们可以在对象的任何位置监听变化,因此当特定值发生变化时,React 组件可以进行更新,而持久性插件可以在整个树中的任何内容发生变化时进行更新。Legend-State 的 Observables 使用 Proxy 以独特的方式跟踪对象中的路径,这使得它非常快速,并且不修改底层数据。

Legend-State 在速度和内存使用方面击败了其他 React 状态库。针对数组的优化模式可以仅重新渲染更改的元素,而不是整个数组,使其比通常使用 React 实现的速度更快 - 在下面的表格中的左侧可以看到来自 krausest 基准测试的情况。

【译】介绍 Legend-State 1.0:更快地构建应用程序

🦄 尽可能简单易用

没有样板代码,没有上下文、操作、reducer、dispatchers、saga、thunk 或 epic。只需调用 get() 获取原始数据,调用 set() 进行更改。

在 React 中,有一个 observer HOC 或 useSelector 钩子来获取数据。只需访问 observables,你的组件就会自动更新。

// 创建一个 observable 对象
const state = observable({ settings: { theme: 'dark' } })

// 只需获取和设置
state.settings.theme.get() === 'dark'
state.settings.theme.set('light')

/ 当访问的 observables 发生更改时,observe 会重新运行
observe(() => {
    console.log(state.settings.theme.get())
})

// 1. Observer 组件会自动跟踪 observables,并在其发生变化时重新渲染change
const Component = observer(function Component() {
    const theme = state.settings.theme.get()

    return <div>Theme: {theme}</div>
})

// 2. 或者 useSelector 钩子获取和跟踪 observables,并返回原始值
function Component2() {
    const count = useSelector(state.count);

    // Re-renders whenever count changes
    return <div>{count}</div>
}

虽然我们的主要目标是实现最快的性能和最佳的 DX,但我们最为兴奋的是它带来的更简单的 React 工作方式:观察状态的变化,而不是通过重新渲染来管理钩子重新运行。如果你愿意,你现在可以完全跳过整个 React 开发层(如果你想的话)。

我们构建应用程序的速度更快,因为它的心智模型更简单,而且即使不考虑性能,我们的应用程序也表现更好。

🔥 细粒度的响应性以实现最小的渲染

我们希望我们的应用程序既能非常快速,又能易于构建。因此,Legend-State 使细粒度的响应性成为一种自然而然的方式,从而减少了更少和更小的重新渲染,同时实际上减少了复杂性。

  • 文本元素在其变化时重新渲染自己
  • 当状态改变时,响应式属性会自行更新
  • 控制流组件在需要时重新渲染自己
  • 输入元素的双向绑定 而且它们所有这些都不需要重新渲染组件本身。

请参阅我们之前的文章“通过默认和真正响应式的方式使 React 变得更快”,了解更多关于这种方法的动机和好处。但现在这里有一个示例:

function Component({ children }) {
  // This component only renders once
  const state = useObservable({ show: false, toggles: 0, text: 'Change me' })

  useInterval(() => {
    state.show.set(v => !v)
    state.numToggles.set(v => v + 1)
  }, 1000)

  // Props ending in $ bind the prop to the observable
  // for tiny targeted re-renders on changes
  return (
    <div>
      <Legend.input value$={state.text} />
      <Legend.div
        className$={() => (
          state.text.get().includes('Legend') && 'font-bold text-blue-500'
        )}
      >
        {state.text}
      </Legend.div>
      <div>
        Modal toggles: {state.numToggles}
      </div>
      <Show
        if={state.show}
        else={<div>Not showing modal</div>}
      >
        <div>Modal</div>
      </Show>
    </div>
  )
}

当然,你也可以使用 observer 或 useSelector,但这种微更新是提高性能的一种很好的方式,一旦你习惯了它,它就会感觉非常自然。

💾 内置持久性

应用程序状态几乎总是需要保存和同步,因此 Legend-State 已经内置了这一功能。你可以使用单个命令持久化整个 observable 对象或子树。

// 状态在启动时自动加载,并在任何更改时保存。轻松 😌。
persistObservable(state, {
    local: 'State',
    persistLocal: ObservablePersistIndexedDB,
})

1.0 版本附带了用于 Web 的 Local Storage 和 IndexedDB 插件,以及用于 React Native 的 react-native-mmkv 插件。

我们还拥有一个 Firebase 实时数据库插件,它是 LegendBravely 的同步系统的支柱,我们将很快发布它,并希望能够提供更多的同步服务。借助它,你的整个同步系统可能如下所示:

persistObservable(userData, {
    persistLocal: ObservablePersistLocalStorage,
    persistRemote: ObservablePersistFirebaseDatabase,
    local: 'User',
    remote: {
        firebase: {
            syncPath: (uid) => `/users/${uid}/`
        }
    }
})

远程同步功能非常齐全 - 它可以在离线时工作并在联机时解决冲突,可以仅同步自上次更新以来的更改,支持加密和字段转换等功能... 但我们将在将来的更新中详细介绍这些内容。

🤟 入门指南

查看文档GitHub 存储库,以了解如何开始使用 Legend-State。我们非常乐意在 GitHub 上听取您的意见,或者直接在 Twitter 上与 LegendApp进行交流。

或者,如果你只是想立即尝试一下,这里有一个可以玩耍的沙盒:

import { useObservable, enableLegendStateReact } from '@legendapp/state/react'
import { useRef } from 'react'
import { useInterval } from './useInterval'

enableLegendStateReact()

export default function Counter() {
  const renderCount = ++useRef(0).current;
  const count = useObservable(1)

  useInterval(() => {
    count.set(v => v + 1)
  }, 600)

  return (
    <div>
        <div>Renders: {renderCount}</div>
        <div>Count: {count}</div>
    </div>
  )
}

👉 下一步

我们很快会在存储库中添加 Firebase 实时数据库持久化插件。然后,我们希望为其他服务添加更多的持久化插件。

细粒度的响应性特性对于我们来说仍然是一种新的范式,因此我们正在评估如何以更简洁的方式实现其最佳实践,并改进与服务器渲染和静态生成的集成。我们还希望添加更多的工具和插件来支持开发者的工作流程。

我们将继续保持开发社区的密切合作,以确定下一个重大功能和改进,这将使 Legend-State 成为开发人员首选的 React 状态管理库。

感谢您的支持和关注!我们很期待您使用 Legend-State 并听取您的反馈。祝你构建快乐!

转载自:https://juejin.cn/post/7237426124669632569
评论
请登录