fly63前端网

www.fly63.com

首页文章资源工具教程 栏目
  • 关于我们
  • 网站投稿
  • 赞助一下
搜索

在线工具_工作生活好帮手

打造各种简单、易用、便捷的在线工具,网友无需注册和下载安装即可使用

点击查看

关闭

提交网站

Valtio
分享
复制链接
新浪微博
QQ 好友

扫一扫分享

网站地址:https://valtio.pmnd.rs/
GitHub:https://github.com/pmndrs/valtio
网站描述:使 React 和 Vanilla 的代理状态变得简单

npm i valtio使代理状态变得简单

Valtio 的优点

  • 概念简单,就是一个 proxy
  • 文档友好,各种应用场景都有举例
  • 使用方式和 api 简单,易于上手和使用,几乎没有什么心智负担...
  • 有 devtools api,完美支持 Debug
  • 当然,完全支持 TypeScript

使用体验下来,简直就是 react 版本的 Pinia。

包装你的状态对象

Valtio 将您传递给它的对象转变为一个自我感知的代理。

import { proxy, useSnapshot } from 'valtio'

const state = proxy({ count: 0, text: 'hello' })

从任何地方变异

您可以按照与普通 js 对象相同的方式对其进行更改。

setInterval(() => {
  ++state.count
}, 1000)

通过 useSnapshot 做出反应

创建捕获更改的本地快照。经验法则:从渲染函数中的快照读取,否则使用源。仅当您访问的状态部分发生更改时,该组件才会重新渲染,它是渲染优化的。

// This will re-render on `state.count` change but not on `state.text` change
function Counter() {
  const snap = useSnapshot(state)
  return (
    <div>
      {snap.count}
      <button onClick={() => ++state.count}>+1</button>
    </div>
  )
}

注意:useSnapshot 返回一个新的代理以进行渲染优化。

TypeScript 用户注意:useSnapshot 的返回类型可能过于严格。

如果您对此不熟悉,强烈建议使用 eslint-plugin-valtio。

从任何地方订阅

您可以访问组件外部的状态并订阅更改。

import { subscribe } from 'valtio'

// Subscribe to all state changes
const unsubscribe = subscribe(state, () =>
  console.log('state has changed to', state),
)
// Unsubscribe by calling the result
unsubscribe()

您还可以订阅状态的一部分。

const state = proxy({ obj: { foo: 'bar' }, arr: ['hello'] })

subscribe(state.obj, () => console.log('state.obj has changed to', state.obj))
state.obj.foo = 'baz'

subscribe(state.arr, () => console.log('state.arr has changed to', state.arr))
state.arr.push('world')

要订阅状态的原始值,请考虑subscribeKey在 utils 中。

import { subscribeKey } from 'valtio/utils'

const state = proxy({ count: 0, text: 'hello' })
subscribeKey(state, 'count', (v) =>
  console.log('state.count has changed to', v),
)

还有另一个实用程序watch在某些情况下可能会很方便。

import { watch } from 'valtio/utils'

const state = proxy({ count: 0 })
const stop = watch((get) => {
  console.log('state has changed to', get(state)) // auto-subscribe on use
})

暂停您的组件

Valtio 支持 React-suspense 并将抛出您在组件渲染函数中访问的承诺。这消除了所有异步来回,您可以直接访问数据,而父级负责回退状态和错误处理。

const state = proxy({ post: fetch(url).then((res) => res.json()) })

function Post() {
  const snap = useSnapshot(state)
  return <div>{snap.post.title}</div>
}

function App() {
  return (
    <Suspense fallback={<span>waiting...</span>}>
      <Post />
    </Suspense>
  )
}

将对象保持在状态而不跟踪它们

如果您有大型嵌套对象以及您不想代理的访问器,这可能很有用。ref允许您将这些对象保留在状态模型中。

有关更多信息,请参阅#61和#178 。

import { proxy, ref } from 'valtio'

const state = proxy({
  count: 0,
  dom: ref(document.body),
})

瞬时更新(针对经常发生的状态更改)

您可以读取组件中的状态,而不会导致重新渲染。

function Foo() {
  const { count, text } = state
  // ...

或者,您可以通过订阅 useEffect 来获得更多控制。

function Foo() {
  const total = useRef(0)
  useEffect(() => subscribe(state.arr, () => {
    total.current = state.arr.reduce((p, c) => p + c)
  }), [])
  // ...

同步更新

默认情况下,状态突变在触发重新渲染之前进行批处理。有时,我们想禁用批处理。已知的用例是<input> #270。

function TextBox() {
  const snap = useSnapshot(state, { sync: true })
  return (
    <input value={snap.text} onChange={(e) => (state.text = e.target.value)} />
  )
}

开发工具

您可以将Redux DevTools Extension用于普通对象和数组。

import { devtools } from 'valtio/utils'

const state = proxy({ count: 0, text: 'hello' })
const unsub = devtools(state, { name: 'state name', enabled: true })

使用 Redux DevTools 操作状态

使用vanilla

Valtio 不依赖于 React,您可以在 vanilla-js 中使用它。

import { proxy, subscribe, snapshot } from 'valtio/vanilla'
// import { ... } from 'valtio/vanilla/utils'

const state = proxy({ count: 0, text: 'hello' })

subscribe(state, () => {
  console.log('state is mutated')
  const obj = snapshot(state) // A snapshot is an immutable object
})

useProxy实用程序

虽然代理状态与其快照的分离很重要,但它会让初学者感到困惑。我们有一个方便的实用程序来改善开发人员体验。 useProxy 返回浅代理状态及其快照,这意味着您只能在根级别上进行变异。

import { useProxy } from 'valtio/utils'

const state = proxy({ count: 1 })

const Component = () => {
  // useProxy returns a special proxy that can be used both in render and callbacks
  // The special proxy has to be used directly in a function scope. You can't destructure it outside the scope.
  const $state = useProxy(state)
  return (
    <div>
      {$state.count}
      <button onClick={() => ++$state.count}>+1</button>
    </div>
  )
}

计算属性

您可以使用对象 getter 定义计算属性。

const state = proxy({
  count: 1,
  get doubled() {
    return this.count * 2
  },
})

将其视为高级用法,因为 的行为this有时会令人困惑。

欲了解更多信息,请查看本指南。

proxyWithHistory实用程序

这是一个实用函数,用于创建具有快照历史记录的代理。

import { proxyWithHistory } from 'valtio-history'

const state = proxyWithHistory({ count: 0 })
console.log(state.value) // ---> { count: 0 }
state.value.count += 1
console.log(state.value) // ---> { count: 1 }
state.undo()
console.log(state.value) // ---> { count: 0 }
state.redo()
console.log(state.value) // ---> { count: 1 }

proxySet实用程序

这是为了创建一个模仿本机 Set 行为的代理。该API与Set API相同

import { proxySet } from 'valtio/utils'

const state = proxySet([1, 2, 3])
//can be used inside a proxy as well
//const state = proxy({
//    count: 1,
//    set: proxySet()
//})

state.add(4)
state.delete(1)
state.forEach((v) => console.log(v)) // 2,3,4

proxyMap实用程序

这是为了创建一个模拟本机 Map 行为的代理。 API与地图API相同

import { proxyMap } from 'valtio/utils'

const state = proxyMap([
  ['key', 'value'],
  ['key2', 'value2'],
])
state.set('key', 'value')
state.delete('key')
state.get('key') // ---> value
state.forEach((value, key) => console.log(key, value)) // ---> "key", "value", "key2", "value2"

兼容性

Valtio 与 React 一起使用并支持钩子 (>=16.8)。它仅依赖于react任何渲染器并与任何渲染器配合使用,例如react-dom、react-native、react-three-fiber等。

Valtio 适用于 Node.js、Next.js 和其他框架。

Valtio 也可以在没有 React 的情况下工作。

链接: https://fly63.com/nav/4050

more>>
相关栏目
layer
layer是一款口碑极佳的web弹层组件
点击进入GitHub
iScroll.js
IScroll是移动页面上被使用的一款仿系统滚动插件。
官网GitHub
wangEditor
基于javascript和css开发的 Web富文本编辑器
官网GitHub
ueditor
由百度web前端研发部开发所见即所得富文本web编辑器
官网GitHub
highlight
Highlight.js 是一个用 JavaScript 写的代码高亮插件,在客户端和服务端都能工作。
官网GitHub
UglifyJS
一个js 解释器、最小化器、压缩器、美化器工具集
官网GitHub
lozad.js
高性能,轻量级,可配置的懒加载图片工具
官网GitHub
Sortable.js
简单灵活的 JavaScript 拖放排序插件
官网GitHub
validate.js
表单提供了强大的验证功能,让客户端表单验证变得更简单
官网GitHub
Draggin.js
一款兼容移动手机的js拖拽插件
官网GitHub
lazysizes.js
响应式图像延迟加载JS插件【懒加载】
官网GitHub
cropper.js
通过canvas实现图片裁剪
官网GitHub
clipboard.js
浏览器中复制文本到剪贴板的插件,不需要Flash,仅仅2kb
官网GitHub
siema
轻量级简单的纯 Js轮播插件
官网GitHub
Mermrender
用于生成序列和UML图的RESTful渲染管道
官网GitHub
Editor.js
JSON格式输出数据的富文本和媒体编辑器
官网GitHub

手机预览