Valtio状态管理学习笔记

2 篇文章 0 订阅
1 篇文章 0 订阅

本人主要是在react中用到了valtio,遇到了相关问题,记录一下。

首先,两个API,是最基础的也是最重要的,proxy与useSnapshot。

proxy

代理状态,将要管理的值用proxy代理起来

import { proxy } from 'valtio'

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

useSnapshot

得到具有响应式只读的值

const snap = useSnapshot(state)

在react中,想实时监听值的变化,用useSnapshot搭配useEffect即可


ref

用ref代理某个值后,改变该值,不会触发监听

subscribe/subscribeKey/watch都不会触发

export const store = proxy<{ refTest: number[] }>({
  refTest: ref([0])
})

subscribe

不能写在组件内,否则会因组件的重新渲染而重复生成

  • 可以监听一个整个proxy
  • 也可以值监听里面的某个值,但这个值必须是复杂数据类型
  • 返回值可以停止订阅
const unsubscribe = subscribe(store, () =>
  console.log('store has changed to', store)
)

snapshot

获取代理并返回一个不可变的对象

proxy发生变化,这个对象也不会更改

import { proxy, snapshot } from 'valtio'

const store = proxy({ name: 'Mika' })
const unwrappedStore = snapshot(store) // unwrapped store is the original object, unproxied
const anotherUnwrappedStore = snapshot(store)
console.log(unwrappedStore === anotherUnwrappedStore) // true
store.name = 'Hanna'
const yetAnotherUpwrappedStore = snapshot(store)
console.log(unwrappedStore === yetAnotherUpwrappedStore) // false

subscribeKey

不能写在组件内,否则会因组件的重新渲染而重复生成

订阅一个值。官网说订阅一个基本数据类型

subscribeKey(store, 'todos', v => {
  console.log(v, 'todos')
})

watch

不能写在组件内,否则会因组件的重新渲染而重复生成

  • 会立即执行一次
  • 参数:一个函数,函数参数是一个方法,传入proxy即可监听
  • 可以return一个函数,该函数会在watch之前运行
watch(get => {
  console.log(get(store))
  return () => {
    if (store.boolean === true) {
      console.log(123)
    }
  }
})
setTimeout(() => {
  store.boolean = true
}, 1000)
// 先log了123,再log get(store)

devtools

调试工具,将proxy放进去即可,然后就可以在浏览器用redux调试工具查看状态了

devtools(store, { name: 'store', enabled: true })

derive/underive

类似于计算属性

const derived = derive({
  doubled: get => get(store).count * 2
})

<div>{derived.doubled}</div>

可以调用underive停止监听


proxyWithHistory

这个API代理会记录历史记录

undo上一个记录

redo下一个记录

export const historyProxy = proxyWithHistory({ num: 0 })

const { value, undo, redo } = useSnapshot(historyProxy)
<button onClick={() => historyProxy.value.num++}>+1</button>
<button onClick={() => undo()}>undo</button>
<button onClick={() => redo()}>redo</button>

proxySet

只能设置number数组

import { proxySet } from 'valtio/utils'

const state = proxySet([1, 2, 3])

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

亦可把proxySet放到proxy中

import { proxySet } from 'valtio/utils'

const state = proxy({
  count: 1,
  set: proxySet(),
})

proxyMap

用法和原生Map一样,但若在proxy用new Map(),值发生变化是不会触发监听的,用proxyMap则可以触发监听

亦可把proxyMap放到proxy中

import { proxyMap } from 'valtio/utils'

const state = proxy({
  count: 1,
  map: proxyMap(),
})

可以用ref作为key

// with ref
const key = ref({})
state.set(key, 'hello')
state.get(key) //hello

// without ref
const key = {}
state.set(key, 'value')
state.get(key) //undefined

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值