zustand-signal 中文文档教程
zustand-signal
Zustand 的另一个 React 绑定
它是什么
通常,Zustand store 是一个 React hook,您可以在 React 中使用。 有一个名为 use-zustand 的替代库。
该库提供了另一种方法。 它遵循 jotai-signal, 这是 @preact/signals-react 的变体。
它允许在 React 中使用 Zustand 存储,而无需使用钩子。 我们不需要遵循钩子规则。
如何使用它
/** @jsxImportSource zustand-signal */
import createStore from 'zustand/vanilla';
import { $ } from 'zustand-signal';
const store = createStore((set) => ({
count: 0,
inc: () => set((state) => ({ count: state.count + 1 })),
}));
setInterval(() => {
store.getState().inc();
}, 100);
const Counter = () => (
<div>
Count: {$(store).count)}
</div>
);
如何工作
第一行的 pragma 就可以解决这个问题。 它将带有信号的代码转换为React可以处理的代码。
原始代码
/** @jsxImportSource zustand-signal */
const Counter = () => (
<div>
Count: {$(store).count} ({Math.random()})
</div>
);
伪转换代码
import { useEffect, useMemo, useReducer } from 'react';
const Counter = () => {
const [, rerender] = useReducer((c) => c + 1, 0);
useEffect(() => {
let lastValue;
const unsubscribe = store.subscribe(() => {
const nextValue = store.getState().count;
if (lastValue !== nextValue) {
lastValue = nextValue;
rerender();
}
});
return unsubscribe;
}, []);
return (
<div>
{useMemo(() => 'Count: '), []}
{store.getState().count}
{useMemo(() => ` (${Math.random()})`, [])}
</div>
);
};
zustand-signal
Another React binding for Zustand
What it is
Typically, Zustand store is a React hook you can just use in React. There's alternative library called use-zustand.
This library provides yet another method. It follows jotai-signal, which is a variant of @preact/signals-react.
It allows to use the Zustand store in React without using hooks. We don't need to follow the rules of hooks.
How to use it
/** @jsxImportSource zustand-signal */
import createStore from 'zustand/vanilla';
import { $ } from 'zustand-signal';
const store = createStore((set) => ({
count: 0,
inc: () => set((state) => ({ count: state.count + 1 })),
}));
setInterval(() => {
store.getState().inc();
}, 100);
const Counter = () => (
<div>
Count: {$(store).count)}
</div>
);
How it works
The pragma at the first line does the trick. It will transform the code with signal to the code that React can handle.
Original code
/** @jsxImportSource zustand-signal */
const Counter = () => (
<div>
Count: {$(store).count} ({Math.random()})
</div>
);
Pseudo transformed code
import { useEffect, useMemo, useReducer } from 'react';
const Counter = () => {
const [, rerender] = useReducer((c) => c + 1, 0);
useEffect(() => {
let lastValue;
const unsubscribe = store.subscribe(() => {
const nextValue = store.getState().count;
if (lastValue !== nextValue) {
lastValue = nextValue;
rerender();
}
});
return unsubscribe;
}, []);
return (
<div>
{useMemo(() => 'Count: '), []}
{store.getState().count}
{useMemo(() => ` (${Math.random()})`, [])}
</div>
);
};