Ant Design Table vs. Data Items: Ensuring Unique rowKey Without Public Exposure?
0 reputation · 16 Dec 2020, 15:47 UTC
0 reputation · 16 Dec 2020, 15:47 UTC
In Ant Design Table, the rowKey prop is mandatory for stable rendering. The default key is the string 'key', so data objects without a key property cause React to reuse the same key for every row.
This silent failure generates duplicate key warnings, unstable row ordering, and can expose sensitive identifiers if the key is derived from a private field. The documentation states that rowKey is required but offers no guidance for non‑unique or absent values, leaving developers to choose ad‑hoc solutions such as the array index.
Using the index breaks selection, sorting, and editing when the dataset changes, yet it is the most common workaround. The lack of a clear fallback or error handling creates an unresolved decision point for developers who need to avoid accidental public exposure.
What strategies can be employed to guarantee unique rowKey values without leaking sensitive data? How should Ant Design evolve its Table component to provide a safe default or validation mechanism when rowKey is missing or non‑unique? Are there recommended patterns for generating deterministic keys that remain stable across reorders yet remain internal?
To guarantee a stable rowKey without exposing sensitive data, generate a deterministic identifier that is derived only from non‑sensitive fields or maintain an internal map of stable IDs.
<Table rowKey={(record) => record.id} />
import { createHash } from 'crypto';
function makeKey(record) {
const source = JSON.stringify({ name: record.name, createdAt: record.createdAt });
return createHash('sha256').update(source).digest('hex').slice(0, 8);
}
<Table rowKey={makeKey} />
Map (or a WeakMap if you prefer automatic cleanup). Return that ID via rowKey. This keeps the key completely internal and stable across reorders, additions, or removals as long as the map persists:
const internalIdMap = new Map();
let nextId = 1;
function getInternalId(record) {
if (!internalIdMap.has(record)) {
internalIdMap.set(record, nextId++);
}
return internalIdMap.get(record);
}
<Table rowKey={getInternalId} />
rowKey is missing or when duplicate keys are detected.keyGenerator prop that defaults to a safe internal‑map strategy, removing the need for developers to implement their own fallback.stableHash(record, fields)) in the docs to help teams create deterministic, non‑exposed keys.Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.