JotaiJotai

Jotai
React 原始而灵活的状态管理

调试

在基本的应用中,console.log 可以是我们调试原子的最好朋友,但是当应用变得更大,我们需要使用更多的原子时,日志可能不是调试原子的好方法。 Jotai 提供了两种调试原子的方法,React Dev ToolsRedux Dev tools。对于读取值和简单的调试,React Dev Tools 可能适合你,但对于更复杂的任务,如时间旅行和设置值,Redux Dev Tools 可能是更好的选择。

调试标签

值得一提的是,我们在 Jotai 中有一个叫做 调试标签 的概念,它可能会帮助我们进行调试。 默认情况下,每个 Jotai 状态都有像 1:<no debugLabel> 这样的标签,数字是自动分配给每个原子的内部 key。但是你可以使用 debugLabel 给原子添加标签,以便更容易地区分它们。

const countAtom = atom(0)
// 默认情况下,countAtom 的 debugLabel 是 'atom1'
if (process.env.NODE_ENV !== 'production') {
countAtom.debugLabel = 'count'
// 现在 debugLabel 是 'count'
}

Jotai 提供了一个 Babel 和一个 SWC 插件,它们会自动为每个原子添加一个 debugLabel,这使得事情对我们来说更容易。更多信息,请查看 jotai/babel@swc-jotai/debug-label

使用 React Dev Tools

你可以使用 React Dev Tools 来检查 Jotai 状态。为了实现这一点,我们在自定义钩子中使用了 useDebugValue。请记住,它只在开发模式下工作 (例如 NODE_ENV === 'development')。

useAtom

useAtom 为原子值调用 useDebugValue,所以如果你在 React Dev Tools 中选择使用 Jotai 原子的组件,你会看到每个在组件中使用的原子都有一个 "Atom" 钩子,以及它现在的值。

useAtomsDebugValue

useAtomsDebugValue 捕获 Provider 下的组件树中的所有原子(或者对于无 Provider 模式的整个树),并为所有原子值使用 useDebugValue。 如果你在 React Dev Tools 中导航到有 useAtomsDebugValue 的组件,我们可以看到一个自定义钩子 "AtomsDebugValue",它允许你查看所有原子值及其依赖项。

一个用例是将钩子放在 Provider 组件下:

const DebugAtoms = () => {
useAtomsDebugValue()
return null
}
const Root = () => (
<Provider>
<DebugAtoms />
<App />
</Provider>
)

使用 Redux DevTools

你也可以使用 Redux DevTools 来检查原子,它有许多功能,如时间旅行和值分派。

useAtomDevtools

useAtomDevtools 是一个 React 钩子,它为特定的原子管理 ReduxDevTools 扩展。

如果你有一个特定的原子你可能想要调试,useAtomDevtools 可以是一个好选择。

const countAtom = atom(0)
// 如果我们有更多的原子,建议设置 countAtom.debugLabel
function Counter() {
const [count, setCount] = useAtom(countAtom)
useAtomDevtools(countAtom)
}

现在如果我们尝试 setCount,我们可以看到 Redux Dev Tools 立即记录了这些更改。

时间旅行

有时我们需要切换到我们原子状态的特定值,有了时间旅行,这是可能的。 你可以在 devtools 中看到每个动作上的 Jump 选项,点击它,你就能切换到那个特定的值。

暂停

如果我们不记录原子上的更改,我们可以使用暂停功能停止观察这些原子。

调度

我们可以使用调度功能在原子上设置值。你可以通过点击显示调度器按钮来实现这一点。 这将把 countAtoms 的值设置为 5

我们应该注意,值将由 JSON.parse 解析,所以传递支持的值。

useAtomsDevtools

useAtomsDevtoolsuseAtomDevtools 的全能版本,它显示存储中的所有原子,而不是显示一个特定的原子。

如果你想在一个地方跟踪所有的原子,我们推荐这个钩子。这意味着每一个在这个钩子底部(在 React 树中)的原子上的每一个动作都会被 Redux Dev Tools 捕获。

useAtomDevtools 的每一个功能在这个钩子中都被支持,但是还有一个额外的功能,它包括提供更多关于原子依赖的信息,如:

{
"values": {
"atom1:count": 0,
"atom2:doubleCount": 0,
"atom3:half": 0,
"atom4:sum": 0
},
"dependents": {
"atom1:count": ["atom1:count", "atom2:doubleCount", "atom4:sum"],
"atom2:doubleCount": ["atom3:half", "atom4:sum"],
"atom3:half": ["atom4:sum"],
"atom4:sum": []
}
}

冻结原子

为了找到你意外尝试改变存储在原子中的对象的错误,你可以使用 jotai/utils 包中的 freezeAtomfreezeAtomCreator。它返回一个深度冻结的原子值,使用 Object.freeze

freezeAtom

freezeAtom(anAtom): AtomType

freezeAtom 接受一个现有的原子并使其"冻结"。 它返回相同的原子。 原子值将被 Object.freeze 深度冻结。 它对于找到你无意中尝试改变对象(状态)的错误非常有用,这可能会导致意外的行为。 你可以使用 freezeAtom 与所有原子一起防止这种情况。

参数

anAtom (必需): 你希望冻结的原子。

示例

import { atom } from 'jotai'
import { freezeAtom } from 'jotai/utils'
const objAtom = freezeAtom(atom({ count: 0 }))

freezeAtomCreator

如果你需要,你可以为 freezeAtom 定义一个工厂。

import { freezeAtom } from 'jotai/utils'
export function freezeAtomCreator<
CreateAtom extends (...args: unknown[]) => Atom<unknown>,
>(createAtom: CreateAtom): CreateAtom {
return ((...args: unknown[]) => freezeAtom(createAtom(...args))) as never
}