or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

app-container.mdbuild-integration.mdcomponent-utilities.mdconfiguration.mdhot-wrapper.mdindex.md

app-container.mddocs/

0

# App Container

1

2

The `AppContainer` component is an error boundary that manages the hot reload lifecycle and provides error handling during development. It wraps React components to catch and display errors without crashing the entire application.

3

4

## Capabilities

5

6

### AppContainer Component

7

8

React component that serves as an error boundary and container for hot-reloadable components.

9

10

```typescript { .api }

11

/**

12

* Error boundary component for hot reload management

13

* Catches errors during development and provides error recovery

14

*/

15

class AppContainer extends React.Component<AppContainerProps & AppChildren> {

16

constructor(props: AppContainerProps & AppChildren);

17

18

/** Catches errors during component rendering */

19

componentDidCatch(error: Error, errorInfo: React.ErrorInfo): void;

20

21

/** Renders children with error boundary protection */

22

render(): React.ReactElement;

23

24

/** Retries after a hot loader error */

25

retryHotLoaderError(): void;

26

}

27

28

interface AppContainerProps {

29

/** Enable/disable error boundary functionality (default: true) */

30

errorBoundary?: boolean;

31

/** Custom error reporter component */

32

errorReporter?: React.ComponentType<ErrorReporterProps>;

33

}

34

35

interface AppChildren {

36

/** Single React element to wrap (validated) */

37

children?: React.ReactElement<any>;

38

}

39

40

interface ErrorReporterProps {

41

error: any;

42

errorInfo?: React.ErrorInfo;

43

component?: AppContainer;

44

}

45

```

46

47

**Usage Examples:**

48

49

```javascript

50

// Basic usage (legacy pattern)

51

import React from 'react';

52

import ReactDOM from 'react-dom';

53

import { AppContainer } from 'react-hot-loader';

54

import App from './App';

55

56

const render = (Component) => {

57

ReactDOM.render(

58

<AppContainer>

59

<Component />

60

</AppContainer>,

61

document.getElementById('root')

62

);

63

};

64

65

render(App);

66

67

// Enable hot reloading

68

if (module.hot) {

69

module.hot.accept('./App', () => {

70

render(App);

71

});

72

}

73

```

74

75

```javascript

76

// With custom error reporter

77

import { AppContainer } from 'react-hot-loader';

78

79

const CustomErrorDisplay = ({ error, errorInfo, component }) => (

80

<div className="error-boundary">

81

<h1>Development Error</h1>

82

<p>{error.message}</p>

83

<button onClick={() => component.retryHotLoaderError()}>

84

Try Again

85

</button>

86

</div>

87

);

88

89

const Root = () => (

90

<AppContainer

91

errorReporter={CustomErrorDisplay}

92

errorBoundary={true}

93

>

94

<App />

95

</AppContainer>

96

);

97

```

98

99

```javascript

100

// Disabled error boundary

101

import { AppContainer } from 'react-hot-loader';

102

103

const Root = () => (

104

<AppContainer errorBoundary={false}>

105

<App />

106

</AppContainer>

107

);

108

```

109

110

### Error Handling

111

112

AppContainer provides comprehensive error handling during development:

113

114

```javascript

115

// Automatic error catching

116

const ProblematicComponent = () => {

117

// This error will be caught by AppContainer

118

throw new Error('Something went wrong!');

119

return <div>This won't render</div>;

120

};

121

122

const App = () => (

123

<AppContainer>

124

<ProblematicComponent />

125

</AppContainer>

126

);

127

// Error display instead of app crash

128

```

129

130

### Error Recovery

131

132

Built-in error recovery mechanism for hot reload errors:

133

134

```javascript

135

const ErrorReporter = ({ error, errorInfo, component }) => (

136

<div className="hot-reload-error">

137

<h2>Hot Reload Error</h2>

138

<details>

139

<summary>Error Details</summary>

140

<pre>{error.stack}</pre>

141

<pre>{JSON.stringify(errorInfo, null, 2)}</pre>

142

</details>

143

144

{/* Retry button triggers error recovery */}

145

<button onClick={() => component.retryHotLoaderError()}>

146

Retry Hot Reload

147

</button>

148

</div>

149

);

150

```

151

152

## Hot Reload Integration

153

154

### State Management

155

AppContainer manages hot reload state internally:

156

157

```javascript

158

// Internal state tracking (not directly accessible)

159

state = {

160

error: null,

161

errorInfo: null,

162

generation: 0 // Hot reload generation tracking

163

}

164

```

165

166

### Lifecycle Integration

167

```javascript

168

// AppContainer integrates with React lifecycle

169

static getDerivedStateFromProps(nextProps, prevState) {

170

// Resets error state on hot reload

171

if (prevState.generation !== getGeneration()) {

172

return {

173

error: null,

174

generation: getGeneration(),

175

};

176

}

177

return null;

178

}

179

180

shouldComponentUpdate(prevProps, prevState) {

181

// Prevents infinite error loops

182

if (prevState.error && this.state.error) {

183

return false;

184

}

185

return true;

186

}

187

```

188

189

## Production Behavior

190

191

In production builds, AppContainer becomes a simple pass-through component:

192

193

```javascript

194

// Production AppContainer (simplified)

195

function AppContainer(props) {

196

return React.Children.only(props.children);

197

}

198

```

199

200

## Advanced Usage

201

202

### Custom Error Reporters

203

204

```javascript

205

import { AppContainer } from 'react-hot-loader';

206

207

// Full-featured error reporter

208

const AdvancedErrorReporter = ({ error, errorInfo, component }) => {

209

const [expanded, setExpanded] = React.useState(false);

210

211

return (

212

<div style={{

213

padding: '20px',

214

backgroundColor: '#ffe6e6',

215

border: '1px solid #ff9999'

216

}}>

217

<h2>πŸ”₯ Hot Reload Error</h2>

218

<p><strong>Error:</strong> {error.message}</p>

219

220

<button onClick={() => setExpanded(!expanded)}>

221

{expanded ? 'Hide' : 'Show'} Details

222

</button>

223

224

{expanded && (

225

<div>

226

<h3>Stack Trace:</h3>

227

<pre style={{ overflow: 'auto', maxHeight: '200px' }}>

228

{error.stack}

229

</pre>

230

231

<h3>Component Stack:</h3>

232

<pre style={{ overflow: 'auto', maxHeight: '200px' }}>

233

{errorInfo.componentStack}

234

</pre>

235

</div>

236

)}

237

238

<div style={{ marginTop: '10px' }}>

239

<button onClick={() => component.retryHotLoaderError()}>

240

πŸ”„ Retry

241

</button>

242

<button onClick={() => window.location.reload()}>

243

πŸ”ƒ Reload Page

244

</button>

245

</div>

246

</div>

247

);

248

};

249

250

// Usage with custom reporter

251

<AppContainer errorReporter={AdvancedErrorReporter}>

252

<App />

253

</AppContainer>

254

```

255

256

### Multiple Children Validation

257

258

AppContainer enforces single child requirement:

259

260

```javascript

261

// βœ… Valid: Single child

262

<AppContainer>

263

<App />

264

</AppContainer>

265

266

// ❌ Invalid: Multiple children (throws error)

267

<AppContainer>

268

<Header />

269

<Main />

270

<Footer />

271

</AppContainer>

272

273

// βœ… Valid: Single wrapper element

274

<AppContainer>

275

<div>

276

<Header />

277

<Main />

278

<Footer />

279

</div>

280

</AppContainer>

281

```

282

283

## Migration Notes

284

285

### Modern vs Legacy Usage

286

287

```javascript

288

// ❌ Legacy pattern (still works)

289

import { AppContainer } from 'react-hot-loader';

290

291

const render = (Component) => {

292

ReactDOM.render(

293

<AppContainer>

294

<Component />

295

</AppContainer>,

296

document.getElementById('root')

297

);

298

};

299

300

// βœ… Modern pattern (recommended)

301

import { hot } from 'react-hot-loader/root';

302

303

const App = () => <div>My App</div>;

304

305

export default hot(App);

306

// AppContainer is included automatically

307

```

308

309

### Error Boundary Best Practices

310

311

```javascript

312

// βœ… Good: Let AppContainer handle hot reload errors

313

<AppContainer errorBoundary={true}>

314

<App />

315

</AppContainer>

316

317

// ⚠️ Caution: Custom error boundaries might interfere

318

class MyErrorBoundary extends React.Component {

319

// Might catch errors that AppContainer should handle

320

}

321

322

// βœ… Better: Disable AppContainer error boundary if using custom

323

<AppContainer errorBoundary={false}>

324

<MyErrorBoundary>

325

<App />

326

</MyErrorBoundary>

327

</AppContainer>

328

```