タプルモードルール
Anonymous tuple modeはモジュールレベルのエクスポート用で、ランタイムキーにはnamed tuple helperを使用します。
Anonymous tuple modeはモジュールのトップレベルのみです。
createRxState(defaultValue)は呼び出すたびに新しいストアを作成します。したがって、関数やコンポーネント内部ではなく、モジュールの最上位で一度作成してエクスポートして使用する必要があります。このモードはストレージオプションを受け取らず、スタックトレースを隠されたキーとして使用しません。
tsx
import { createRxState } from "@byeolnaerim/global-rx-state";
// Good: module top-level에서 한 번 생성합니다.
export const [setCount, getCount, useCount] = createRxState(0);
export function Counter() {
const count = useCount();
//Don't Do That: 컴포넌트나 함수 내부에서 anonymous tuple store를 만들지 마세요.
//매 렌더마다 새 store가 만들어질 수 있습니다.
//const [setCount, getCount, useCount] = createRxState(0);
return (
<button onClick={() => setCount((prev) => prev + 1)}>
{count}
</button>
);
}ランタイムキーにはnamed tuple helperを使用
createRxStateTupleはサーバーから受け取ったワークスペースID、ユーザーが選択したタブ名、ルートパラメータのように名前が事前に確定しない場合に適しています。同じランタイムキーは同じストアを再利用し、異なるキーは異なるストアを使用します。
tsx
function RuntimeKeySample() {
const [setActiveTab, , useActiveTab] = createRxStateTuple(
"profile",
"docsRuntimeActiveTab",
{ storage: "sessionstorage" },
);
const activeTab = useActiveTab();
const [setDraft, , useDraft] = createRxStateTuple(
{ title: "", content: "" },
`docs-tab-draft:${activeTab}`,
{ storage: "sessionstorage" },
);
const draft = useDraft();
return (
<Paper variant="outlined" sx={{ p: 2, borderRadius: 3 }}>
<Stack spacing={1.5}>
<Stack direction="row" spacing={1}>
{["profile", "settings", "billing"].map((tab) => (
<Button
key={tab}
variant={
activeTab === tab ? "contained" : "outlined"
}
onClick={() => setActiveTab(tab)}
>
{tab}
</Button>
))}
</Stack>
<TextField
label={`Draft for ${activeTab}`}
value={draft.content}
onChange={(event) =>
setDraft((prev) => ({
...prev,
content: event.target.value,
}))
}
fullWidth
/>
</Stack>
</Paper>
);
}