or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

async-loading.mddata-management.mddrag-drop.mdindex.mdselection-checking.mdtree-component.mdtree-node.mdvirtual-scrolling.md

data-management.mddocs/

0

# Data Management

1

2

RC Tree supports flexible data management through both JSX children and data-driven approaches, with customizable field mappings and comprehensive type-safe data structures.

3

4

## Capabilities

5

6

### Data Structure Types

7

8

Core data types for representing tree nodes with comprehensive type safety and customization options.

9

10

```typescript { .api }

11

/**

12

* Base interface for tree data nodes with common properties

13

*/

14

interface BasicDataNode {

15

/** Enable/disable checkbox for this node */

16

checkable?: boolean;

17

/** Disable all interactions for this node */

18

disabled?: boolean;

19

/** Disable only checkbox interactions */

20

disableCheckbox?: boolean;

21

/** Custom icon for this node */

22

icon?: IconType;

23

/** Mark as leaf node (no children) */

24

isLeaf?: boolean;

25

/** Enable/disable selection for this node */

26

selectable?: boolean;

27

/** Custom expand/collapse icon */

28

switcherIcon?: IconType;

29

/** CSS class for styling */

30

className?: string;

31

/** Inline styles */

32

style?: React.CSSProperties;

33

}

34

35

/**

36

* Generic wrapper type for custom data with tree functionality

37

* @param T - Custom data type

38

* @param ChildFieldName - Field name for children array (default: 'children')

39

*/

40

type FieldDataNode<T, ChildFieldName extends string = 'children'> = BasicDataNode &

41

T &

42

Partial<Record<ChildFieldName, FieldDataNode<T, ChildFieldName>[]>>;

43

44

/**

45

* Standard data node structure with key and title

46

*/

47

type DataNode = FieldDataNode<{

48

key: Key;

49

title?: React.ReactNode | ((data: DataNode) => React.ReactNode);

50

}>;

51

52

/**

53

* Enhanced data node with event state information

54

*/

55

type EventDataNode<TreeDataType> = {

56

key: Key;

57

expanded: boolean;

58

selected: boolean;

59

checked: boolean;

60

loaded: boolean;

61

loading: boolean;

62

halfChecked: boolean;

63

dragOver: boolean;

64

dragOverGapTop: boolean;

65

dragOverGapBottom: boolean;

66

pos: string;

67

active: boolean;

68

} & TreeDataType & BasicDataNode;

69

```

70

71

### Field Name Mapping

72

73

Customize field names for data-driven trees to work with existing data structures.

74

75

```typescript { .api }

76

/**

77

* Configuration for mapping custom field names to tree properties

78

*/

79

interface FieldNames {

80

/** Field name for node display title (default: 'title') */

81

title?: string;

82

/** Internal title field mapping for complex scenarios */

83

_title?: string[];

84

/** Field name for unique node identifier (default: 'key') */

85

key?: string;

86

/** Field name for child nodes array (default: 'children') */

87

children?: string;

88

}

89

```

90

91

**Usage Examples:**

92

93

### Basic Data-Driven Tree

94

95

```typescript

96

import React, { useState } from "react";

97

import Tree from "rc-tree";

98

99

const BasicDataTree = () => {

100

const treeData = [

101

{

102

key: '0-0',

103

title: 'Parent Node',

104

children: [

105

{

106

key: '0-0-0',

107

title: 'Child Node 1',

108

isLeaf: true,

109

},

110

{

111

key: '0-0-1',

112

title: 'Child Node 2',

113

children: [

114

{

115

key: '0-0-1-0',

116

title: 'Grandchild Node',

117

isLeaf: true,

118

},

119

],

120

},

121

],

122

},

123

];

124

125

return (

126

<Tree

127

prefixCls="rc-tree"

128

treeData={treeData}

129

defaultExpandAll

130

/>

131

);

132

};

133

```

134

135

### Custom Field Mapping

136

137

```typescript

138

import React from "react";

139

import Tree from "rc-tree";

140

141

const CustomFieldTree = () => {

142

// Data with custom field names

143

const customData = [

144

{

145

id: '1',

146

name: 'Root Category',

147

subcategories: [

148

{

149

id: '1-1',

150

name: 'Electronics',

151

subcategories: [

152

{ id: '1-1-1', name: 'Phones' },

153

{ id: '1-1-2', name: 'Laptops' },

154

],

155

},

156

{

157

id: '1-2',

158

name: 'Books',

159

subcategories: [],

160

},

161

],

162

},

163

];

164

165

const fieldNames = {

166

title: 'name',

167

key: 'id',

168

children: 'subcategories',

169

};

170

171

return (

172

<Tree

173

prefixCls="rc-tree"

174

treeData={customData}

175

fieldNames={fieldNames}

176

defaultExpandAll

177

/>

178

);

179

};

180

```

181

182

### Rich Data with Custom Properties

183

184

```typescript

185

import React from "react";

186

import Tree from "rc-tree";

187

188

interface CustomNodeData {

189

key: string;

190

title: string;

191

type: 'folder' | 'file';

192

size?: number;

193

modified?: Date;

194

children?: CustomNodeData[];

195

}

196

197

const RichDataTree = () => {

198

const richTreeData: CustomNodeData[] = [

199

{

200

key: '0-0',

201

title: 'Documents',

202

type: 'folder',

203

modified: new Date('2024-01-15'),

204

children: [

205

{

206

key: '0-0-0',

207

title: 'report.pdf',

208

type: 'file',

209

size: 2048,

210

modified: new Date('2024-01-10'),

211

isLeaf: true,

212

},

213

{

214

key: '0-0-1',

215

title: 'presentation.pptx',

216

type: 'file',

217

size: 5120,

218

modified: new Date('2024-01-12'),

219

isLeaf: true,

220

disabled: true, // File is read-only

221

},

222

],

223

},

224

];

225

226

const titleRender = (nodeData: CustomNodeData) => (

227

<span>

228

{nodeData.type === 'folder' ? 'πŸ“' : 'πŸ“„'} {nodeData.title}

229

{nodeData.size && (

230

<span style={{ color: '#999', marginLeft: 8 }}>

231

({Math.round(nodeData.size / 1024)}KB)

232

</span>

233

)}

234

</span>

235

);

236

237

return (

238

<Tree

239

prefixCls="rc-tree"

240

treeData={richTreeData}

241

titleRender={titleRender}

242

defaultExpandAll

243

/>

244

);

245

};

246

```

247

248

### Dynamic Data with Async Loading

249

250

```typescript

251

import React, { useState } from "react";

252

import Tree from "rc-tree";

253

254

interface AsyncNodeData {

255

key: string;

256

title: string;

257

isLeaf?: boolean;

258

children?: AsyncNodeData[];

259

}

260

261

const AsyncDataTree = () => {

262

const [treeData, setTreeData] = useState<AsyncNodeData[]>([

263

{

264

key: '0-0',

265

title: 'Lazy Parent',

266

children: [], // Empty children for lazy loading

267

},

268

]);

269

const [loadedKeys, setLoadedKeys] = useState<string[]>([]);

270

271

const loadData = async (treeNode: any) => {

272

const { key } = treeNode;

273

274

// Simulate API call

275

await new Promise(resolve => setTimeout(resolve, 1000));

276

277

// Generate children data

278

const children = [

279

{

280

key: `${key}-0`,

281

title: `Child ${key}-0`,

282

isLeaf: true,

283

},

284

{

285

key: `${key}-1`,

286

title: `Child ${key}-1`,

287

isLeaf: true,

288

},

289

];

290

291

// Update tree data

292

setTreeData(prevData => {

293

const updateNode = (nodes: AsyncNodeData[]): AsyncNodeData[] => {

294

return nodes.map(node => {

295

if (node.key === key) {

296

return { ...node, children };

297

}

298

if (node.children) {

299

return { ...node, children: updateNode(node.children) };

300

}

301

return node;

302

});

303

};

304

return updateNode(prevData);

305

});

306

307

setLoadedKeys(prev => [...prev, key]);

308

};

309

310

return (

311

<Tree

312

prefixCls="rc-tree"

313

treeData={treeData}

314

loadData={loadData}

315

loadedKeys={loadedKeys}

316

/>

317

);

318

};

319

```

320

321

## Data Structure Patterns

322

323

### Flat Data Conversion

324

325

```typescript { .api }

326

/**

327

* Convert flat array data to hierarchical tree structure

328

*/

329

interface FlatDataItem {

330

id: string;

331

parentId?: string;

332

title: string;

333

[key: string]: any;

334

}

335

336

/**

337

* Utility type for flattened tree node with hierarchy information

338

*/

339

interface FlattenNode<TreeDataType extends BasicDataNode = DataNode> {

340

parent: FlattenNode<TreeDataType> | null;

341

children: FlattenNode<TreeDataType>[];

342

pos: string;

343

data: TreeDataType;

344

title: React.ReactNode;

345

key: Key;

346

isStart: boolean[];

347

isEnd: boolean[];

348

}

349

```

350

351

**Usage Example:**

352

353

```typescript

354

import React from "react";

355

import Tree from "rc-tree";

356

357

const FlatDataTree = () => {

358

const flatData = [

359

{ id: '1', title: 'Root' },

360

{ id: '2', parentId: '1', title: 'Child 1' },

361

{ id: '3', parentId: '1', title: 'Child 2' },

362

{ id: '4', parentId: '2', title: 'Grandchild 1' },

363

];

364

365

// Convert flat data to tree structure

366

const buildTreeData = (flatData: any[]) => {

367

const map = new Map();

368

const roots: any[] = [];

369

370

// Create map of all items

371

flatData.forEach(item => {

372

map.set(item.id, { ...item, key: item.id, children: [] });

373

});

374

375

// Build tree structure

376

flatData.forEach(item => {

377

const node = map.get(item.id);

378

if (item.parentId) {

379

const parent = map.get(item.parentId);

380

if (parent) {

381

parent.children.push(node);

382

}

383

} else {

384

roots.push(node);

385

}

386

});

387

388

return roots;

389

};

390

391

const treeData = buildTreeData(flatData);

392

393

return (

394

<Tree

395

prefixCls="rc-tree"

396

treeData={treeData}

397

defaultExpandAll

398

/>

399

);

400

};

401

```

402

403

### Type-Safe Custom Data

404

405

```typescript

406

import React from "react";

407

import Tree from "rc-tree";

408

409

// Define your custom data structure

410

interface FileSystemNode {

411

key: string;

412

title: string;

413

type: 'file' | 'directory';

414

permissions: string;

415

owner: string;

416

size?: number;

417

children?: FileSystemNode[];

418

}

419

420

const TypeSafeDataTree = () => {

421

const fileSystemData: FileSystemNode[] = [

422

{

423

key: '/home',

424

title: 'home',

425

type: 'directory',

426

permissions: 'drwxr-xr-x',

427

owner: 'root',

428

children: [

429

{

430

key: '/home/user',

431

title: 'user',

432

type: 'directory',

433

permissions: 'drwxr-xr-x',

434

owner: 'user',

435

children: [

436

{

437

key: '/home/user/document.txt',

438

title: 'document.txt',

439

type: 'file',

440

permissions: '-rw-r--r--',

441

owner: 'user',

442

size: 1024,

443

isLeaf: true,

444

},

445

],

446

},

447

],

448

},

449

];

450

451

return (

452

<Tree<FileSystemNode>

453

prefixCls="rc-tree"

454

treeData={fileSystemData}

455

titleRender={(node) => (

456

<span>

457

{node.type === 'directory' ? 'πŸ“' : 'πŸ“„'} {node.title}

458

<span style={{ color: '#666', fontSize: '0.8em', marginLeft: 8 }}>

459

{node.permissions} {node.owner}

460

</span>

461

</span>

462

)}

463

defaultExpandAll

464

/>

465

);

466

};

467

```

468

469

## Key Management

470

471

### Key Requirements

472

473

```typescript { .api }

474

/**

475

* Key types for tree node identification

476

*/

477

type Key = React.Key; // string | number

478

type SafeKey = Exclude<Key, bigint>; // Excludes bigint for index compatibility

479

480

/**

481

* Key entity mapping for efficient tree operations

482

*/

483

type KeyEntities<DateType extends BasicDataNode = any> = Record<

484

SafeKey,

485

DataEntity<DateType>

486

>;

487

488

/**

489

* Data entity with hierarchy information

490

*/

491

interface DataEntity<TreeDataType extends BasicDataNode = DataNode> {

492

node: TreeDataType;

493

nodes: TreeDataType[];

494

key: Key;

495

pos: string;

496

index: number;

497

parent?: DataEntity<TreeDataType>;

498

children?: DataEntity<TreeDataType>[];

499

level: number;

500

}

501

```

502

503

**Key Management Best Practices:**

504

505

```typescript

506

// βœ… Good: Unique, stable keys

507

const goodTreeData = [

508

{ key: 'user-1', title: 'John Doe' },

509

{ key: 'user-2', title: 'Jane Smith' },

510

];

511

512

// ❌ Bad: Non-unique or unstable keys

513

const badTreeData = [

514

{ key: 1, title: 'First' }, // Numbers can conflict

515

{ key: 1, title: 'Second' }, // Duplicate key

516

];

517

518

// βœ… Good: Hierarchical keys for complex structures

519

const hierarchicalData = [

520

{

521

key: 'department-engineering',

522

title: 'Engineering',

523

children: [

524

{ key: 'team-frontend', title: 'Frontend Team' },

525

{ key: 'team-backend', title: 'Backend Team' },

526

],

527

},

528

];

529

```