JotaiJotai

状態
Primitive and flexible state management for React

Devtools

安装

您必须安装 jotai-devtools 才能使用此功能。

npm install jotai-devtools
# or
yarn add jotai-devtools

useAtomsDebugValue

useAtomsDebugValue 是一个 React hook,它将在 React Devtools 中显示所有原子值。

function useAtomsDebugValue(options?: {
scope?: Scope;
enabled?: boolean;
}): void;

在内部,它使用仅在 DEV 模式下有效的 useDebugValue。 它将捕获所有可从 hook 所在位置访问的原子。

示例

import { useAtomsDebugValue } from "jotai-devtools";
const textAtom = atom("hello");
textAtom.debugLabel = "textAtom";
const lenAtom = atom((get) => get(textAtom).length);
lenAtom.debugLabel = "lenAtom";
const TextBox = () => {
const [text, setText] = useAtom(textAtom);
const [len] = useAtom(lenAtom);
return (
<span>
<input value={text} onChange={(e) => setText(e.target.value)} />({len})
</span>
);
};
const DebugAtoms = () => {
useAtomsDebugValue();
return null;
};
const App = () => (
<Provider>
<DebugAtoms />
<TextBox />
</Provider>
);

useAtomDevtools

useAtomDevtools 是一个 React hook,用于管理特定原子的 ReduxDevTools 集成。

function useAtomDevtools<Value>(
anAtom: WritableAtom<Value, Value>,
options?: {
name?: string;
scope?: Scope;
enabled?: boolean;
}
): void;

useAtomDevtools hook 接受一个泛型类型参数(镜像存储在原子中的类型)。 此外,该 hook 接受两个调用参数,anAtomnameanAtom 是将附加到 devtools 实例的原子。 name 是一个可选参数,用于定义 devtools 实例的调试标签。 如果 name 未定义,将使用 atom.debugLabel 代替。

示例

import { useAtomDevtools } from "jotai-devtools";
// 存储在原子中的类型的接口。
export interface Task {
label: string;
complete: boolean;
}
// 要调试的原子。
export const tasksAtom = atom<Task[]>([]);
// 如果 useAtomDevtools name 参数未定义,将使用此值代替。
tasksAtom.debugLabel = "Tasks";
export const useTasksDevtools = () => {
// hook 可以简单地通过传递一个用于调试的原子来调用。
useAtomDevtools(tasksAtom);
// 指定自定义类型参数
useAtomDevtools<Task[]>(tasksAtom);
// 您可以将两个 devtools 实例附加到同一个原子,并使用自定义名称来区分它们。
useAtomDevtools(tasksAtom, "Tasks (Instance 1)");
useAtomDevtools(tasksAtom, "Tasks (Instance 2)");
};

useAtomsDevtools

⚠️ 注意:这个 hook 是实验性的(欢迎提供反馈)并且只能在 process.env.NODE_ENV !== 'production' 环境中工作。

useAtomsDevtoolsuseAtomDevtools 的包罗万象的版本,它显示 store 中的所有原子,而不是显示特定的原子。

function useAtomsDevtools(
name: string,
options?: {
scope?: Scope;
enabled?: boolean;
}
): void;

它需要一个命名 Redux devtools 实例所需的 name 参数和一个 scope 参数(如果 hook 用于特定范围的原子)。

作为此 API 的一个限制,我们需要将 useAtomsDevtools 放在一个组件中,其中消耗的 atom 应该位于 React 树的较低位置而不是该组件(下例中的 AtomsDevtools)。 AtomsDevtools 组件可以被视为我们应用程序的最佳实践。

示例

const countAtom = atom(0);
const doubleCountAtom = atom((get) => get(countAtom) * 2);
function Counter() {
const [count, setCount] = useAtom(countAtom);
const [doubleCount] = useAtom(doubleCountAtom);
...
}
const AtomsDevtools = ({ children }) => {
useAtomsDevtools('demo')
return children
}
export default function App() {
return (
<AtomsDevtools>
<Counter />
</AtomsDevtools>
)
}

useAtomsSnapshot

⚠️ 注意:此 hook 仅适用于 process.env.NODE_ENV !== 'production' 环境。 它在生产中返回一个静态的空值。

useAtomsSnapshot 获取当前安装的原子及其状态的快照。

function useAtomsSnapshot(scope?: Scope): AtomsSnapshot;

它接受一个原子 scope 参数并将返回一个 AtomsSnapshot,它基本上是一个 Map<AnyAtom, unknown>。 您可以使用 Map API 迭代原子及其状态。 这个 hook 主要用于调试和 devtools 用例。

使用这个 hook 要小心,因为它会导致组件为所有状态更改重新渲染。

示例

import { Provider } from "jotai";
import { useAtomsSnapshot } from "jotai-devtools";
const RegisteredAtoms = () => {
const atoms = useAtomsSnapshot();
return (
<div>
<p>Atom count: {atoms.size}</p>
<div>
{Array.from(atoms).map(([atom, atomValue]) => (
<p key={`${atom}`}>{`${atom.debugLabel}: ${atomValue}`}</p>
))}
</div>
</div>
);
};
const App = () => (
<Provider>
<RegisteredAtoms />
</Provider>
);

useGotoAtomsSnapshot

⚠️ 注意:此 hook 仅适用于 process.env.NODE_ENV !== 'production' 环境。 它在生产环境中就像一个空函数。

useGotoAtomsSnapshot 将更新当前的 Jotai 状态以匹配传递的快照。

function useGotoAtomsSnapshot(
scope?: Scope
): (values: Iterable<readonly [AnyAtom, unknown]>) => void;

这个 hook 返回一个回调,它从 useAtomsSnapshot hook 中获取一个 snapshot 并将更新 Jotai 状态。 它接受一个原子 scope 参数,如果原子具有混合范围,则会出错。 这个 hook 主要用于调试和 devtools 用例。

示例

import { Provider } from "jotai";
import { useAtomsSnapshot, useGotoAtomsSnapshot } from "jotai-devtools";
const petAtom = atom("cat");
const colorAtom = atom("blue");
const UpdateSnapshot = () => {
const snapshot = useAtomsSnapshot();
const goToSnapshot = useGotoAtomsSnapshot();
return (
<button
onClick={() => {
const newSnapshot = new Map(snapshot);
newSnapshot.set(petAtom, "dog");
newSnapshot.set(colorAtom, "green");
goToSnapshot(newSnapshot);
}}
>
Go to snapshot
</button>
);
};