or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

components.mdcontext.mdelement-creation.mdhooks.mdindex.mdreact-compatibility.mdrendering.md

rendering.mddocs/

0

# Rendering System

1

2

Universal rendering engine that works across multiple platforms through pluggable driver system. Enables Rax applications to run on Web, Weex, Node.js, Alibaba MiniApp, WeChat MiniProgram, and other platforms.

3

4

## Capabilities

5

6

### Render Function

7

8

Renders Rax elements to a container using the specified platform driver. This is the main entry point for displaying Rax applications.

9

10

```javascript { .api }

11

/**

12

* Renders a Rax element tree to a container

13

* @param element - Root Rax element to render

14

* @param container - DOM container or platform-specific container

15

* @param options - Render options including driver and other settings

16

* @param callback - Optional callback executed after render completion

17

* @returns Component instance of the root element

18

*/

19

function render(element, container, options, callback);

20

21

/**

22

* Simplified render function (callback as third parameter)

23

* @param element - Root Rax element to render

24

* @param container - DOM container or platform-specific container

25

* @param callback - Optional callback executed after render completion

26

* @returns Component instance of the root element

27

*/

28

function render(element, container, callback);

29

```

30

31

**Usage Examples:**

32

33

```javascript

34

import { createElement, render, Component } from 'rax';

35

import * as DriverDOM from 'driver-dom'; // Web platform driver

36

37

// Basic functional component

38

function App() {

39

return createElement('div', null,

40

createElement('h1', null, 'Hello Rax!'),

41

createElement('p', null, 'Universal React-compatible rendering')

42

);

43

}

44

45

// Render to DOM (Web platform)

46

const appInstance = render(

47

createElement(App),

48

document.getElementById('root'),

49

{ driver: DriverDOM },

50

() => {

51

console.log('App rendered successfully');

52

}

53

);

54

55

// Simplified usage with callback

56

render(

57

createElement(App),

58

document.body,

59

() => {

60

console.log('Render complete');

61

}

62

);

63

```

64

65

### Render Options

66

67

The render function accepts various options to customize rendering behavior:

68

69

```javascript { .api }

70

interface RenderOptions {

71

/**

72

* Platform driver for rendering (required)

73

* Defines how elements are created and managed on the target platform

74

*/

75

driver: Driver;

76

77

/**

78

* Enable hydration mode for server-side rendered content

79

* When true, Rax will attach to existing DOM instead of creating new elements

80

*/

81

hydrate?: boolean;

82

83

/**

84

* Parent element context for nested rendering

85

* Used internally for component composition

86

*/

87

parent?: RaxElement;

88

}

89

```

90

91

### Platform Drivers

92

93

Rax uses drivers to abstract platform-specific rendering logic. Each platform has its own driver implementation:

94

95

**Web Platform (driver-dom):**

96

97

```javascript

98

import { createElement, render } from 'rax';

99

import * as DriverDOM from 'driver-dom';

100

101

function WebApp() {

102

return createElement('div', null,

103

createElement('button', {

104

onClick: () => alert('Clicked!')

105

}, 'Click me')

106

);

107

}

108

109

render(createElement(WebApp), document.body, { driver: DriverDOM });

110

```

111

112

**Server-Side Rendering:**

113

114

```javascript

115

import { createElement, render } from 'rax';

116

import * as DriverServer from 'driver-server';

117

118

function ServerApp() {

119

return createElement('html', null,

120

createElement('head', null,

121

createElement('title', null, 'SSR App')

122

),

123

createElement('body', null,

124

createElement('h1', null, 'Server Rendered'),

125

createElement('p', null, 'This was rendered on the server')

126

)

127

);

128

}

129

130

// Server-side rendering

131

const htmlString = render(createElement(ServerApp), null, { driver: DriverServer });

132

```

133

134

**Weex Platform:**

135

136

```javascript

137

import { createElement, render } from 'rax';

138

import * as DriverWeex from 'driver-weex';

139

140

function WeexApp() {

141

return createElement('div', {

142

style: {

143

flex: 1,

144

justifyContent: 'center',

145

alignItems: 'center'

146

}

147

},

148

createElement('text', {

149

style: { fontSize: 48, color: '#333' }

150

}, 'Weex App')

151

);

152

}

153

154

render(createElement(WeexApp), null, { driver: DriverWeex });

155

```

156

157

### Hydration

158

159

Hydration allows Rax to attach to server-side rendered HTML instead of creating new DOM elements:

160

161

```javascript { .api }

162

/**

163

* Hydrates server-side rendered content

164

* Attaches Rax to existing DOM elements instead of creating new ones

165

*/

166

function hydrate(element, container, options, callback);

167

```

168

169

**Hydration Usage Example:**

170

171

```javascript

172

import { createElement, render } from 'rax';

173

import * as DriverDOM from 'driver-dom';

174

175

function HydratedApp() {

176

return createElement('div', { id: 'app' },

177

createElement('h1', null, 'Hydrated App'),

178

createElement('button', {

179

onClick: () => console.log('Hydrated click!')

180

}, 'Interactive Button')

181

);

182

}

183

184

// Hydrate existing server-rendered HTML

185

render(

186

createElement(HydratedApp),

187

document.getElementById('app'),

188

{

189

driver: DriverDOM,

190

hydrate: true

191

},

192

() => {

193

console.log('Hydration complete - app is now interactive');

194

}

195

);

196

```

197

198

### Multiple Root Rendering

199

200

Rax supports rendering multiple independent component trees:

201

202

**Multiple Roots Example:**

203

204

```javascript

205

import { createElement, render } from 'rax';

206

import * as DriverDOM from 'driver-dom';

207

208

// Header component

209

function AppHeader() {

210

return createElement('header', null,

211

createElement('h1', null, 'My App'),

212

createElement('nav', null,

213

createElement('a', { href: '/' }, 'Home'),

214

createElement('a', { href: '/about' }, 'About')

215

)

216

);

217

}

218

219

// Sidebar component

220

function AppSidebar() {

221

return createElement('aside', null,

222

createElement('h2', null, 'Sidebar'),

223

createElement('ul', null,

224

createElement('li', null, 'Item 1'),

225

createElement('li', null, 'Item 2')

226

)

227

);

228

}

229

230

// Main content component

231

function AppMain() {

232

return createElement('main', null,

233

createElement('h2', null, 'Main Content'),

234

createElement('p', null, 'This is the main content area')

235

);

236

}

237

238

// Render to different containers

239

render(createElement(AppHeader), document.getElementById('header'), { driver: DriverDOM });

240

render(createElement(AppSidebar), document.getElementById('sidebar'), { driver: DriverDOM });

241

render(createElement(AppMain), document.getElementById('main'), { driver: DriverDOM });

242

```

243

244

### Render Lifecycle

245

246

The rendering process follows these steps:

247

248

1. **Element Creation**: `createElement` creates virtual DOM elements

249

2. **Driver Initialization**: Platform driver is initialized with options

250

3. **Component Instantiation**: Components are instantiated and lifecycle methods are called

251

4. **DOM/Platform Updates**: Driver creates or updates platform-specific elements

252

5. **Callback Execution**: Optional callback is executed after render completion

253

254

**Lifecycle Integration Example:**

255

256

```javascript

257

import { createElement, render, Component } from 'rax';

258

import * as DriverDOM from 'driver-dom';

259

260

class LifecycleDemo extends Component {

261

constructor(props) {

262

super(props);

263

console.log('1. Constructor called');

264

this.state = { mounted: false };

265

}

266

267

componentDidMount() {

268

console.log('3. componentDidMount called');

269

this.setState({ mounted: true });

270

}

271

272

componentDidUpdate() {

273

console.log('4. componentDidUpdate called');

274

}

275

276

render() {

277

console.log('2. render called');

278

return createElement('div', null,

279

createElement('p', null, `Mounted: ${this.state.mounted}`)

280

);

281

}

282

}

283

284

render(

285

createElement(LifecycleDemo),

286

document.body,

287

{ driver: DriverDOM },

288

() => {

289

console.log('5. Render callback executed');

290

}

291

);

292

```

293

294

### Error Handling

295

296

Rax provides error boundaries and error handling during rendering:

297

298

```javascript

299

import { createElement, render, Component } from 'rax';

300

import * as DriverDOM from 'driver-dom';

301

302

class ErrorBoundary extends Component {

303

constructor(props) {

304

super(props);

305

this.state = { hasError: false, error: null };

306

}

307

308

componentDidCatch(error, errorInfo) {

309

console.error('Error caught by boundary:', error, errorInfo);

310

this.setState({ hasError: true, error });

311

}

312

313

render() {

314

if (this.state.hasError) {

315

return createElement('div', null,

316

createElement('h2', null, 'Something went wrong'),

317

createElement('p', null, this.state.error?.message || 'Unknown error')

318

);

319

}

320

321

return this.props.children;

322

}

323

}

324

325

function ProblematicComponent() {

326

throw new Error('This component has an error!');

327

}

328

329

function App() {

330

return createElement(ErrorBoundary, null,

331

createElement('h1', null, 'My App'),

332

createElement(ProblematicComponent)

333

);

334

}

335

336

render(createElement(App), document.body, { driver: DriverDOM });

337

```

338

339

## Types

340

341

```javascript { .api }

342

// Render function signatures

343

interface RenderFunction {

344

(element: RaxElement, container: any, options: RenderOptions, callback?: Function): any;

345

(element: RaxElement, container: any, callback?: Function): any;

346

}

347

348

// Render options interface

349

interface RenderOptions {

350

driver: Driver;

351

hydrate?: boolean;

352

parent?: RaxElement;

353

}

354

355

// Driver interface (platform-specific implementation)

356

interface Driver {

357

createElement(type: string, props?: Object): any;

358

createTextNode(text: string): any;

359

createBody(): any;

360

updateElement(element: any, props: Object, prevProps?: Object): void;

361

appendChild(parent: any, child: any): void;

362

removeChild(parent: any, child: any): void;

363

insertBefore(parent: any, child: any, beforeChild: any): void;

364

// Additional platform-specific methods...

365

}

366

367

// Container types (platform-specific)

368

type DOMContainer = Element | Document;

369

type WeexContainer = any; // Weex-specific container type

370

type ServerContainer = null; // Server rendering doesn't use container

371

372

// Render callback type

373

type RenderCallback = () => void;

374

375

// Component instance type (returned by render)

376

interface ComponentInstance {

377

setState?(partialState: any, callback?: Function): void;

378

forceUpdate?(callback?: Function): void;

379

// Additional component instance methods...

380

}

381

```