or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

build-integration.mddynamic-loading.mdindex.mdmulti-resource-loading.mdserver-side-rendering.md

multi-resource-loading.mddocs/

0

# Multi-Resource Loading

1

2

Advanced functionality for loading multiple resources in parallel using `Loadable.Map`. This enables complex loading scenarios where components depend on multiple modules, data sources, or external resources.

3

4

## Capabilities

5

6

### Loadable.Map Function

7

8

Creates a loadable component that loads multiple resources in parallel and provides them to a custom render function.

9

10

```javascript { .api }

11

/**

12

* Creates a loadable component that loads multiple resources in parallel

13

* @param options - Configuration object with loader map and render function

14

* @returns LoadableComponent class

15

*/

16

function LoadableMap(options: LoadableMapOptions): LoadableComponent;

17

18

interface LoadableMapOptions {

19

/** Object mapping keys to loader functions */

20

loader: { [key: string]: () => Promise<any> };

21

/** Component to render during loading/error states */

22

loading: LoadingComponent;

23

/** Required render function to combine loaded resources */

24

render: (loaded: { [key: string]: any }, props: any) => React.ReactElement;

25

/** Delay in milliseconds before showing loading component (default: 200) */

26

delay?: number;

27

/** Timeout in milliseconds before showing timeout state (default: null) */

28

timeout?: number;

29

/** Function returning webpack module IDs for SSR */

30

webpack?: () => number[];

31

/** Array of module paths for SSR */

32

modules?: string[];

33

}

34

```

35

36

**Usage Examples:**

37

38

```javascript

39

import React from 'react';

40

import Loadable from 'react-loadable';

41

42

// Load component and data together

43

const LoadableUserProfile = Loadable.Map({

44

loader: {

45

Component: () => import('./UserProfile'),

46

translations: () => fetch('/api/i18n/user-profile.json').then(res => res.json()),

47

theme: () => import('./themes/default'),

48

},

49

loading: LoadingSpinner,

50

render(loaded, props) {

51

const UserProfile = loaded.Component.default;

52

return (

53

<UserProfile

54

{...props}

55

translations={loaded.translations}

56

theme={loaded.theme.default}

57

/>

58

);

59

},

60

});

61

62

// Load multiple related components

63

const LoadableDashboard = Loadable.Map({

64

loader: {

65

Header: () => import('./DashboardHeader'),

66

Sidebar: () => import('./DashboardSidebar'),

67

Content: () => import('./DashboardContent'),

68

},

69

loading: LoadingDashboard,

70

render(loaded, props) {

71

const Header = loaded.Header.default;

72

const Sidebar = loaded.Sidebar.default;

73

const Content = loaded.Content.default;

74

75

return (

76

<div className="dashboard">

77

<Header user={props.user} />

78

<div className="dashboard-body">

79

<Sidebar />

80

<Content data={props.data} />

81

</div>

82

</div>

83

);

84

},

85

});

86

```

87

88

### Render Function

89

90

The render function is required for `Loadable.Map` and receives all loaded resources as a single object.

91

92

```javascript { .api }

93

/**

94

* Render function for combining multiple loaded resources

95

* @param loaded - Object containing all loaded resources by key

96

* @param props - Props passed to the LoadableComponent

97

* @returns React element combining the loaded resources

98

*/

99

type LoadableMapRenderFunction = (

100

loaded: { [key: string]: any },

101

props: any

102

) => React.ReactElement;

103

```

104

105

**Usage Examples:**

106

107

```javascript

108

// Complex data transformation

109

const LoadableChart = Loadable.Map({

110

loader: {

111

ChartComponent: () => import('./Chart'),

112

data: () => fetch('/api/chart-data').then(res => res.json()),

113

config: () => import('./chart-config.json'),

114

},

115

loading: Loading,

116

render(loaded, props) {

117

const Chart = loaded.ChartComponent.default;

118

const processedData = processChartData(loaded.data, loaded.config);

119

120

return <Chart data={processedData} {...props} />;

121

},

122

});

123

124

// Conditional rendering based on loaded resources

125

const LoadableConditional = Loadable.Map({

126

loader: {

127

AdminPanel: () => import('./AdminPanel'),

128

UserPanel: () => import('./UserPanel'),

129

permissions: () => fetch('/api/user/permissions').then(res => res.json()),

130

},

131

loading: Loading,

132

render(loaded, props) {

133

const isAdmin = loaded.permissions.includes('admin');

134

const Panel = isAdmin ? loaded.AdminPanel.default : loaded.UserPanel.default;

135

136

return <Panel {...props} permissions={loaded.permissions} />;

137

},

138

});

139

```

140

141

## Loading States and Error Handling

142

143

Multi-resource loading handles complex scenarios where some resources may load faster than others or where individual resources may fail.

144

145

### Loading Behavior

146

147

- All resources start loading in parallel

148

- The loading component is displayed until ALL resources complete

149

- If any resource fails, the error state is triggered

150

- Individual resource loading times don't affect the loading state display

151

152

```javascript

153

// Loading component for multi-resource scenarios

154

function MultiResourceLoading(props) {

155

if (props.error) {

156

return (

157

<div className="multi-load-error">

158

<h3>Failed to load resources</h3>

159

<p>One or more required resources failed to load</p>

160

<button onClick={props.retry}>Retry All</button>

161

</div>

162

);

163

}

164

165

if (props.timedOut) {

166

return (

167

<div className="multi-load-timeout">

168

<h3>Loading is taking longer than expected</h3>

169

<button onClick={props.retry}>Retry</button>

170

</div>

171

);

172

}

173

174

if (props.pastDelay) {

175

return (

176

<div className="multi-load-loading">

177

<div>Loading dashboard components...</div>

178

<div className="loading-spinner" />

179

</div>

180

);

181

}

182

183

return null;

184

}

185

```

186

187

## Advanced Patterns

188

189

### Resource Dependencies

190

191

Handle scenarios where some resources depend on others by structuring the loader appropriately.

192

193

```javascript

194

const LoadableWithDependencies = Loadable.Map({

195

loader: {

196

config: () => fetch('/api/config').then(res => res.json()),

197

// Note: All loaders start simultaneously, but you can handle dependencies in render

198

component: () => import('./ConfigurableComponent'),

199

},

200

loading: Loading,

201

render(loaded, props) {

202

const Component = loaded.component.default;

203

204

// Apply configuration to component

205

return <Component config={loaded.config} {...props} />;

206

},

207

});

208

```

209

210

### Dynamic Resource Loading

211

212

Combine static and dynamic resource loading based on props.

213

214

```javascript

215

function createDynamicLoader(locale) {

216

return Loadable.Map({

217

loader: {

218

Component: () => import('./LocalizedComponent'),

219

translations: () => import(`./i18n/${locale}.json`),

220

dateUtils: () => import(`./utils/date-${locale}.js`),

221

},

222

loading: Loading,

223

render(loaded, props) {

224

const Component = loaded.Component.default;

225

return (

226

<Component

227

{...props}

228

translations={loaded.translations}

229

formatDate={loaded.dateUtils.formatDate}

230

/>

231

);

232

},

233

});

234

}

235

236

// Usage

237

const LoadableEnglish = createDynamicLoader('en');

238

const LoadableFrench = createDynamicLoader('fr');

239

```

240

241

### Mixed Resource Types

242

243

Load different types of resources including modules, JSON data, external APIs, and assets.

244

245

```javascript

246

const LoadableRichContent = Loadable.Map({

247

loader: {

248

// React component

249

Editor: () => import('./RichTextEditor'),

250

251

// JSON configuration

252

editorConfig: () => import('./editor-config.json'),

253

254

// External API data

255

userData: () => fetch('/api/user/preferences').then(res => res.json()),

256

257

// Dynamic import based on feature flags

258

plugins: () =>

259

fetch('/api/feature-flags')

260

.then(res => res.json())

261

.then(flags => flags.advancedEditor ?

262

import('./editor-plugins/advanced') :

263

import('./editor-plugins/basic')

264

),

265

},

266

loading: RichContentLoading,

267

render(loaded, props) {

268

const Editor = loaded.Editor.default;

269

270

return (

271

<Editor

272

{...props}

273

config={loaded.editorConfig}

274

userPreferences={loaded.userData}

275

plugins={loaded.plugins.default}

276

/>

277

);

278

},

279

});

280

```