Tuple Mode Rules
Anonymous tuple mode는 module-level export용이고, runtime key에는 named tuple helper를 사용합니다.
Anonymous tuple mode는 module top-level only
createRxState(defaultValue)는 호출할 때마다 새 store를 만듭니다. 따라서 함수나 컴포넌트 내부가 아니라 모듈 최상위에서 한 번 만들고 export해서 사용해야 합니다. 이 모드는 storage option을 받지 않고, stack trace를 숨겨진 key로 사용하지도 않습니다.
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>
);
}Runtime key에는 named tuple helper 사용
createRxStateTuple은 서버에서 받은 workspace id, 사용자가 선택한 tab name, route parameter처럼 name이 미리 확정되지 않는 경우에 적합합니다. 같은 runtime key는 같은 store를 재사용하고, 다른 key는 다른 store를 사용합니다.
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>
);
}