<commit_before># Components

- [Structure](#structure)
- [Lifecycle methods](#lifecycle-methods)
- [State](#state)
- [Avoid-anti-patterns](#avoid-anti-patterns)

### Structure

Components are a mechanism to encapsulate parts of a view to make code easier to organize and/or reuse.

Any Javascript object that has a view method is a Mithril component. Components can be consumed via the [`m()`](hyperscript.md) utility:

```javascript
var Example = {
	view: function() {
		return m("div", "Hello")
	}
}

m(Example)

// equivalent HTML
// <div>Hello</div>
```

---

### Lifecycle methods

Components can have the same [lifecycle methods](lifecycle-methods.md) as virtual DOM nodes: `oninit`, `oncreate`, `onupdate`, `onbeforeremove`, `onremove` and `onbeforeupdate`.

```javascript
var ComponentWithHooks = {
	oninit: function(vnode) {
		console.log("initialized")
	},
	oncreate: function(vnode) {
		console.log("DOM created")
	},
	onupdate: function(vnode) {
		console.log("DOM updated")
	},
	onbeforeremove: function(vnode, done) {
		console.log("exit animation can start")
		done()
	},
	onremove: function(vnode) {
		console.log("removing DOM element")
	},
	onbeforeupdate: function(vnode, old) {
		return true
	},
	view: function(vnode) {
		return "hello"
	}
}
```

Like other types of virtual DOM nodes, components may have additional lifecycle methods defined when consumed as vnode types.

```javascript
function initialize() {
	console.log("initialized as vnode")
}

m(ComponentWithHooks, {oninit: initialize})
```

Lifecycle methods in vnodes do not override component methods, nor vice versa. Component lifecycle methods are always run after the vnode's corresponding method.

To learn more about lifecycle methods, [see the lifecycle methods page](lifecycle-methods.md).

---

### State

Like all virtual DOM nodes, component vnodes can have state. Component state is useful for supporting object-oriented architectures, for encapsulation and for separation of concerns.

The state of a component can be accessed three ways: as a blueprint at initialization, via `vnode.state` and via the `this` keyword in component methods.

#### At initialization
<commit_msg>Add notes about passing data to components, avoid inadvertant lifecycle hooks.<commit_after># Components

- [Structure](#structure)
- [Lifecycle methods](#lifecycle-methods)
- [State](#state)
- [Avoid-anti-patterns](#avoid-anti-patterns)

### Structure

Components are a mechanism to encapsulate parts of a view to make code easier to organize and/or reuse.

Any Javascript object that has a view method is a Mithril component. Components can be consumed via the [`m()`](hyperscript.md) utility:

```javascript
var Example = {
	view: function() {
		return m("div", "Hello")
	}
}

m(Example)

// equivalent HTML
// <div>Hello</div>
```

---

### Passing data to components

Data can be passed to component instances through an `attrs` object as a parameter in the hyperscript function:

```javascript
m(Example, {name: "Floyd"})
```

`attrs` data can be accessed in the component's view or lifecycle methods via the `vnode`:

```javascript
var Example = {
	view: function (vnode) {
		return m("div", "Hello, " + vnode.attrs.name)
	}
}
```

NOTE: Lifecycle methods can also be provided via attrs, so you should avoid using the lifecycle method names for your own callbacks as they will be invoked by Mithril. Use lifecycle methods in `attrs` only when you specifically wish to create lifecycle hooks.

---

### Lifecycle methods

Components can have the same [lifecycle methods](lifecycle-methods.md) as virtual DOM nodes: `oninit`, `oncreate`, `onupdate`, `onbeforeremove`, `onremove` and `onbeforeupdate`.

```javascript
var ComponentWithHooks = {
	oninit: function(vnode) {
		console.log("initialized")
	},
	oncreate: function(vnode) {
		console.log("DOM created")
	},
	onupdate: function(vnode) {
		console.log("DOM updated")
	},
	onbeforeremove: function(vnode, done) {
		console.log("exit animation can start")
		done()
	},
	onremove: function(vnode) {
		console.log("removing DOM element")
	},
	onbeforeupdate: function(vnode, old) {
		return true
	},
	view: function(vnode) {
		return "hello"
	}
}
```

Like other types of virtual DOM nodes, components may have additional lifecycle methods defined when consumed as vnode types.

```javascript
function initialize() {
	console.log("initialized as vnode")
}

m(ComponentWithHooks, {oninit: initialize})
```

Lifecycle methods in vnodes do not override component methods, nor vice versa. Component lifecycle methods are always run after the vnode's corresponding method.

Take care not to use lifecycle method names for your own callback function names in vnodes.

To learn more about lifecycle methods, [see the lifecycle methods page](lifecycle-methods.md).

---

### State

Like all virtual DOM nodes, component vnodes can have state. Component state is useful for supporting object-oriented architectures, for encapsulation and for separation of concerns.

The state of a component can be accessed three ways: as a blueprint at initialization, via `vnode.state` and via the `this` keyword in component methods.

#### At initialization

{'fraction_non_alphanumeric': 0.10902401239349342, 'fraction_numerical': 0.0, 'mean_word_length': 4.809898762654668, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6567726', 'n_tokens_mistral': 1548, 'n_tokens_neox': 1463, 'n_words': 578}