กฎโหมด Tuple
โหมด anonymous tuple เป็นการส่งออกระดับโมดูล และใช้ named tuple helper สำหรับ runtime key.
โหมด anonymous tuple ใช้ได้เฉพาะที่ระดับบนสุดของโมดูลเท่านั้น
createRxState(defaultValue)จะสร้าง store ใหม่ทุกครั้งที่เรียก ดังนั้นควรสร้างและส่งออกจากระดับบนสุดของโมดูล ไม่ใช่ภายในฟังก์ชันหรือคอมโพเนนต์ โหมดนี้ไม่รับ storage option และไม่ใช้ stack trace เป็นคีย์ที่ซ่อนอยู่.
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 สำหรับ runtime key
สร้างคู่สถานะ Rxเหมาะสำหรับกรณีที่ชื่อไม่ถูกกำหนดล่วงหน้า เช่น workspace id ที่ได้รับจากเซิร์ฟเวอร์, ชื่อแท็บที่ผู้ใช้เลือก, หรือพารามิเตอร์เส้นทาง คีย์ runtime เดียวกันจะใช้ store เดียวกัน และคีย์ที่แตกต่างกันจะใช้ 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>
);
}