mirror of
https://github.com/docmost/docmost.git
synced 2026-08-31 19:05:29 +08:00
fix(base): scope per-base UI atoms by pageId to prevent embed render loops
Two BaseTable instances on the same page (e.g. multiple base embeds in one document) shared the same global jotai atoms for activeViewId, editingCell, property menu state, and row selection. Each instance's useEffect that synced activeViewId would clobber the other's value every render, pinning React into a "Maximum update depth exceeded" loop. Convert every UI atom in base-atoms.ts to an atomFamily keyed by pageId so each base owns its own scope, and thread pageId through the grid component tree (GridRow, GridCell, GridHeaderCell, RowNumberCell, RowNumberHeaderCell, PropertyMenuContent) plus useRowSelection so each consumer reaches the per-base atom. use-base-socket already had pageId in scope; its store.get/store.set calls now resolve through selectedRowIdsAtomFamily(pageId) too.
This commit is contained in:
@@ -7,7 +7,7 @@ import {
|
||||
IBaseRow,
|
||||
IBaseView,
|
||||
} from "@/features/base/types/base.types";
|
||||
import { selectedRowIdsAtom } from "@/features/base/atoms/base-atoms";
|
||||
import { selectedRowIdsAtomFamily } from "@/features/base/atoms/base-atoms";
|
||||
import { formulaRecomputeAtom } from "@/features/base/atoms/formula-recompute-atom";
|
||||
import { IPagination } from "@/lib/types";
|
||||
|
||||
@@ -211,11 +211,12 @@ export function useBaseSocket(pageId: string | undefined): void {
|
||||
},
|
||||
);
|
||||
const store = getDefaultStore();
|
||||
const current = store.get(selectedRowIdsAtom);
|
||||
const selectedIdsAtom = selectedRowIdsAtomFamily(pageId);
|
||||
const current = store.get(selectedIdsAtom);
|
||||
if (current.has(e.rowId)) {
|
||||
const next = new Set(current);
|
||||
next.delete(e.rowId);
|
||||
store.set(selectedRowIdsAtom, next);
|
||||
store.set(selectedIdsAtom, next);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -236,14 +237,15 @@ export function useBaseSocket(pageId: string | undefined): void {
|
||||
},
|
||||
);
|
||||
const store = getDefaultStore();
|
||||
const current = store.get(selectedRowIdsAtom);
|
||||
const selectedIdsAtom = selectedRowIdsAtomFamily(pageId);
|
||||
const current = store.get(selectedIdsAtom);
|
||||
if (current.size > 0) {
|
||||
let changed = false;
|
||||
const next = new Set(current);
|
||||
for (const id of e.rowIds) {
|
||||
if (next.delete(id)) changed = true;
|
||||
}
|
||||
if (changed) store.set(selectedRowIdsAtom, next);
|
||||
if (changed) store.set(selectedIdsAtom, next);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ const BATCH_SIZE = 500;
|
||||
|
||||
export function useDeleteSelectedRows(pageId: string) {
|
||||
const { t } = useTranslation();
|
||||
const { selectedIds, clear } = useRowSelection();
|
||||
const { selectedIds, clear } = useRowSelection(pageId);
|
||||
const mutation = useDeleteRowsMutation();
|
||||
|
||||
const runDelete = useCallback(
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { useCallback } from "react";
|
||||
import { useAtom } from "jotai";
|
||||
import {
|
||||
selectedRowIdsAtom,
|
||||
lastToggledRowIndexAtom,
|
||||
selectedRowIdsAtomFamily,
|
||||
lastToggledRowIndexAtomFamily,
|
||||
} from "@/features/base/atoms/base-atoms";
|
||||
|
||||
type ToggleOpts = {
|
||||
@@ -11,13 +11,15 @@ type ToggleOpts = {
|
||||
orderedRowIds: string[];
|
||||
};
|
||||
|
||||
export function useRowSelection() {
|
||||
const [selectedIds, setSelectedIds] = useAtom(selectedRowIdsAtom) as unknown as [
|
||||
export function useRowSelection(pageId: string) {
|
||||
const [selectedIds, setSelectedIds] = useAtom(
|
||||
selectedRowIdsAtomFamily(pageId),
|
||||
) as unknown as [
|
||||
Set<string>,
|
||||
(val: Set<string> | ((prev: Set<string>) => Set<string>)) => void,
|
||||
];
|
||||
const [lastToggledIndex, setLastToggledIndex] = useAtom(
|
||||
lastToggledRowIndexAtom,
|
||||
lastToggledRowIndexAtomFamily(pageId),
|
||||
) as unknown as [number | null, (val: number | null) => void];
|
||||
|
||||
const isSelected = useCallback(
|
||||
|
||||
Reference in New Issue
Block a user