or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

component-system.mdcore-rendering.mdevent-handling.mdfragments-utilities.mdindex.mdrefs.mdvnode-creation.md
tile.json

component-system.mddocs/

0

# Component System

1

2

Class and functional component system with comprehensive lifecycle methods, state management, and performance optimizations.

3

4

## Capabilities

5

6

### Component Class

7

8

Base class for creating stateful components with lifecycle methods and state management.

9

10

```typescript { .api }

11

/**

12

* Base class for creating stateful components

13

*/

14

abstract class Component<P = Record<string, unknown>, S = Record<string, unknown>> {

15

/** Current component state */

16

state: Readonly<S | null>;

17

/** Component props passed from parent */

18

props: Readonly<{ children?: InfernoNode } & P>;

19

/** Context object from parent components */

20

context: any;

21

/** Optional display name for debugging */

22

displayName?: string;

23

24

constructor(props?: P, context?: any);

25

26

/**

27

* Updates component state and triggers re-render

28

* @param newState - New state object or updater function

29

* @param callback - Optional callback called after state update

30

*/

31

setState<K extends keyof S>(

32

newState: ((prevState: Readonly<S>, props: Readonly<{ children?: InfernoNode } & P>) => Pick<S, K> | S | null) | (Pick<S, K> | S | null),

33

callback?: () => void

34

): void;

35

36

/**

37

* Forces component to re-render regardless of shouldComponentUpdate

38

* @param callback - Optional callback called after re-render

39

*/

40

forceUpdate(callback?: (() => void) | undefined): void;

41

42

/**

43

* Renders the component's virtual DOM

44

* @param props - Current props

45

* @param state - Current state

46

* @param context - Current context

47

* @returns Virtual DOM representation

48

*/

49

abstract render(props: Readonly<{ children?: InfernoNode } & P>, state: Readonly<S>, context: any): InfernoNode;

50

51

// Lifecycle methods (optional)

52

componentDidMount?(): void;

53

componentWillMount?(): void;

54

componentWillReceiveProps?(nextProps: Readonly<{ children?: InfernoNode } & P>, nextContext: any): void;

55

shouldComponentUpdate?(nextProps: Readonly<{ children?: InfernoNode } & P>, nextState: Readonly<S>, context: any): boolean;

56

componentWillUpdate?(nextProps: Readonly<{ children?: InfernoNode } & P>, nextState: Readonly<S>, context: any): void;

57

componentDidUpdate?(prevProps: Readonly<{ children?: InfernoNode } & P>, prevState: Readonly<S>, snapshot: any): void;

58

componentWillUnmount?(): void;

59

componentDidAppear?(domNode: Element): void;

60

componentWillDisappear?(domNode: Element, callback: () => void): void;

61

componentWillMove?(parentVNode: VNode, parentDOM: Element, dom: Element): void;

62

getChildContext?(): void;

63

getSnapshotBeforeUpdate?(prevProps: Readonly<{ children?: InfernoNode } & P>, prevState: Readonly<S>): any;

64

65

// Static properties

66

static defaultProps?: Record<string, unknown> | null;

67

static getDerivedStateFromProps?(nextProps: any, state: any): any;

68

}

69

```

70

71

**Usage Examples:**

72

73

```typescript

74

import { Component, createVNode, VNodeFlags } from "inferno";

75

76

class Counter extends Component<{}, { count: number }> {

77

constructor(props) {

78

super(props);

79

this.state = { count: 0 };

80

}

81

82

componentDidMount() {

83

console.log('Counter mounted');

84

}

85

86

increment = () => {

87

this.setState(prevState => ({ count: prevState.count + 1 }));

88

};

89

90

render() {

91

return createVNode(VNodeFlags.HtmlElement, 'div', null, [

92

createVNode(VNodeFlags.HtmlElement, 'h2', null, `Count: ${this.state.count}`),

93

createVNode(VNodeFlags.HtmlElement, 'button', null, 'Increment', ChildFlags.HasInvalidChildren, {

94

onClick: this.increment

95

})

96

]);

97

}

98

}

99

100

// With default props

101

class Greeting extends Component<{ name?: string }> {

102

static defaultProps = { name: 'World' };

103

104

render() {

105

return createVNode(VNodeFlags.HtmlElement, 'h1', null, `Hello, ${this.props.name}!`);

106

}

107

}

108

```

109

110

### Stateless Functional Components

111

112

Function-based components for simple, stateless UI elements.

113

114

```typescript { .api }

115

/**

116

* Function-based components for simple, stateless UI elements

117

*/

118

interface StatelessComponent<P = {}> {

119

(props: { children?: InfernoNode } & P & Refs<P>, context?: any): InfernoElement | null;

120

defaultProps?: Partial<P> | undefined | null;

121

defaultHooks?: Refs<P> | undefined | null;

122

}

123

124

type SFC<P = {}> = StatelessComponent<P>;

125

```

126

127

**Usage Examples:**

128

129

```typescript

130

import { createVNode, VNodeFlags } from "inferno";

131

132

// Simple functional component

133

function Welcome(props) {

134

return createVNode(VNodeFlags.HtmlElement, 'h1', null, `Welcome, ${props.name}!`);

135

}

136

137

// With default props

138

function Button(props) {

139

return createVNode(VNodeFlags.HtmlElement, 'button', props.className, props.children, ChildFlags.HasInvalidChildren, {

140

onClick: props.onClick,

141

disabled: props.disabled

142

});

143

}

144

145

Button.defaultProps = {

146

className: 'btn',

147

disabled: false

148

};

149

150

// With lifecycle hooks

151

function FadeIn(props) {

152

return createVNode(VNodeFlags.HtmlElement, 'div', 'fade-in', props.children);

153

}

154

155

FadeIn.defaultHooks = {

156

onComponentDidAppear(domNode) {

157

domNode.style.opacity = '0';

158

domNode.style.transition = 'opacity 0.3s';

159

setTimeout(() => domNode.style.opacity = '1', 10);

160

}

161

};

162

```

163

164

### Component Types

165

166

Union type for all component types.

167

168

```typescript { .api }

169

/**

170

* Union type for all component types

171

*/

172

type ComponentType<P = Record<string, unknown>> = typeof Component<P> | StatelessComponent<P>;

173

```

174

175

### Re-render Function

176

177

Force re-rendering of all queued components.

178

179

```typescript { .api }

180

/**

181

* Force re-rendering of all queued components

182

* Used internally by the state management system

183

*/

184

function rerender(): void;

185

```

186

187

## Lifecycle Methods

188

189

### Mounting Lifecycle

190

191

Called when component is being created and inserted into the DOM:

192

193

1. **constructor()** - Initialize state and bind methods

194

2. **componentWillMount()** - Called before mounting (deprecated)

195

3. **render()** - Returns virtual DOM representation

196

4. **componentDidMount()** - Called after mounting, ideal for DOM operations

197

198

### Updating Lifecycle

199

200

Called when component props or state changes:

201

202

1. **componentWillReceiveProps(nextProps, nextContext)** - Called when receiving new props

203

2. **shouldComponentUpdate(nextProps, nextState, context)** - Controls whether to re-render

204

3. **componentWillUpdate(nextProps, nextState, context)** - Called before update

205

4. **render()** - Returns updated virtual DOM

206

5. **getSnapshotBeforeUpdate(prevProps, prevState)** - Capture info before DOM changes

207

6. **componentDidUpdate(prevProps, prevState, snapshot)** - Called after update

208

209

### Unmounting Lifecycle

210

211

Called when component is being removed from the DOM:

212

213

1. **componentWillUnmount()** - Cleanup before removal

214

215

### Animation Lifecycle

216

217

Special lifecycle methods for animations:

218

219

- **componentDidAppear(domNode)** - Called when component appears

220

- **componentWillDisappear(domNode, callback)** - Called before disappearing

221

- **componentWillMove(parentVNode, parentDOM, dom)** - Called when moving

222

223

## State Management

224

225

### setState Method

226

227

Updates component state and triggers re-render:

228

229

```typescript

230

// Object update

231

this.setState({ count: 10 });

232

233

// Functional update

234

this.setState(prevState => ({ count: prevState.count + 1 }));

235

236

// With callback

237

this.setState({ loading: false }, () => {

238

console.log('State updated');

239

});

240

```

241

242

### State Update Rules

243

244

1. **Immutability**: Always return new state objects, don't mutate existing state

245

2. **Async Updates**: setState is asynchronous, use callbacks or functional updates for dependent operations

246

3. **Batching**: Multiple setState calls in the same event are batched for performance

247

4. **Constructor Restriction**: Cannot call setState in constructor, assign directly to this.state

248

249

## Context System

250

251

### Providing Context

252

253

```typescript

254

class Provider extends Component {

255

getChildContext() {

256

return { theme: 'dark', locale: 'en' };

257

}

258

259

render() {

260

return this.props.children;

261

}

262

}

263

```

264

265

### Consuming Context

266

267

```typescript

268

class Consumer extends Component {

269

constructor(props, context) {

270

super(props, context);

271

console.log(context.theme); // 'dark'

272

}

273

274

render() {

275

return createVNode(VNodeFlags.HtmlElement, 'div', this.context.theme);

276

}

277

}

278

```

279

280

## Performance Optimizations

281

282

### shouldComponentUpdate

283

284

Prevents unnecessary re-renders:

285

286

```typescript

287

shouldComponentUpdate(nextProps, nextState) {

288

return nextProps.id !== this.props.id || nextState.count !== this.state.count;

289

}

290

```

291

292

### Default Props Merging

293

294

Default props are automatically merged with provided props:

295

296

```typescript

297

class MyComponent extends Component {

298

static defaultProps = { color: 'blue', size: 'medium' };

299

300

render() {

301

// this.props will include default values for missing props

302

return createVNode(VNodeFlags.HtmlElement, 'div', `${this.props.color} ${this.props.size}`);

303

}

304

}

305

```

306

307

### Component Refs

308

309

Access component instances through refs:

310

311

```typescript

312

class Parent extends Component {

313

componentDidMount() {

314

this.childComponent.focus(); // Access child methods

315

}

316

317

render() {

318

return createComponentVNode(

319

VNodeFlags.ComponentClass,

320

ChildComponent,

321

{},

322

null,

323

(instance) => { this.childComponent = instance; }

324

);

325

}

326

}

327

```