Globostate
Globostate是一个 反应钩 这将创建一个全局的、不可变的状态,并允许您使用类似的路径语法来读取和更新它的任何部分 lodash的 _.get 和 _.set 功能。
它看起来是这样的:
const ExampleComponent = () => {
const [count, setCount] = useGloboState('app.components.counterValue', 0)
return (
<main>
<p>You clicked {count} times.</p>
<button onClick={() => setCount(count + 1)}>Click Me</button>
</main>
)
}
开始
Globostate需要React作为对等依赖。首先:
npm i react react-dom globostate
提供者
Globostate包括一个 Provider 必须包装应用程序的组件:
import React from 'react'
import { createRoot } from 'react-dom/client'
import { Provider, useGloboState } from 'globostate'
const container = document.getElementById('app')
const root = createRoot(container)
root.render(
<Provider>
<App />
</Provider>
)
钩子
这个 useGloboState hook的工作原理与React非常相似 useState 但是全局状态可以在应用程序的任何地方访问,而不需要通过props钻取状态。
useGloboState 接受两个参数。第一个是对象路径,用点和括号索引('lists.todos[0].title')或作为键数组(['lists', 'todos', 0, 'title']). 更新是不可变的:只复制该路径上的对象。第二种是初始状态,类似于 useState是唯一的参数。
const [todos, setTodos] = useGloboState('appState.lists.todos', [])
只要路径中还没有存储任何内容,就返回默认值。在调用setter之前,它不会被写入存储中。
更新功能
就像 useState, setter也接受一个函数。它接收当前值(或默认值,如果还没有存储)并返回下一个值:
const [count, setCount] = useGloboState('app.count', 0)
setCount(c => c + 1)
因为传递给setter的函数总是被视为更新器,所以通过包装来存储函数: setHandler(() => myFunction)。
路径
- 点和括号:
'lists.todos[0].title'和'lists.todos.0.title'都是同一条路。 - 键数组:
['lists', 'todos', 0, 'title']. 当键包含点或括号时使用此格式。 - 创建缺失的关卡: 当一个set经过一个还不存在的级别时,如果下一个键是一个非负整数,globostate将创建一个数组(
0,12),否则为普通对象。 - 不支持: 引用的键,如
a["b"]。
重新渲染
组件只有在其路径上的值改变时才会重新呈现。数组和普通对象的比较比较比较浅,所以设置一个相等的副本不会重新渲染。其他所有内容,包括date、Maps、Sets和类实例,都是通过引用进行比较的,所以要替换这些值,而不是改变它们。
独立的商店
Provider 和 useGloboState 共享一个商店。要创建独立存储,例如为自包含的小部件或库创建独立存储,请调用 createProvider:
import { createProvider } from 'globostate'
const { Provider: WidgetProvider, useGloboState: useWidgetState } = createProvider()
需求
- React 18或更新版本。
- globostate作为ES模块发布。
import作品无处不在。加载require()需要节点20.19+或22.12+。
把它们放在一起
完整的应用程序可能是这样的:
import React from 'react'
import { createRoot } from 'react-dom/client'
import { Provider, useGloboState } from 'globostate'
const App = () => {
const [value, updateValue] = useGloboState('app.counterValue', 0)
return (
<main>
<div><button onClick={() => updateValue(value - 1)}>-</button></div>
<div>{value}</div>
<div><button onClick={() => updateValue(value + 1)}>+</button></div>
</main>
)
}
const container = document.getElementById('app')
const root = createRoot(container)
root.render(
<Provider>
<App />
</Provider>
)