# Hooks

## What are Hooks?

Hooks are what Vortex uses to make your code reactive. In essence, hooks are simply functions that fire based on change events. These events are tied to variables. As an example, the `onChange` hook fires whenever a variable that implements the hook changes (essentially whenever `<var> = <value>` is encountered in the interpreter).

```go
var x = 0
var y = 0

x::onChange((data) => {
    y = data.current * 2
})

x = 10
println(y) // 20
```

The implementation of standard hooks has the following syntax:

{% code overflow="wrap" %}

```go
<varName>::<hookName>((data) => {...}, name: optional)
```

{% endcode %}

Note the `data` parameter that we exposed in the above hook. Each hook exposes data that the function can use when it fires. The data object contains three properties:

* old: The old value
* current: The new value
* name: Name of the variable OR custom name if provided

Hooks are a great way implement reactivity in your code. However, hooks do make your code more complex and hard to track if they are overused. Make sure that you structure your code in a way that exposes the hooks and makes them front and centre, so that they can be more easily maintained.

## Hook Recursion

It's possible for hooks to be self-referential, however there are measures in place that protect you from infinitely recursing.

Consider this scenario:

```rust
var x = 0

x::onChange((e) => {
    e.current += 10
})

x = 5

println(x) // Output: 15
```

It's easy to assume that since x (via e.current) is changing inside its own hook, it's going to fire the same hook again and again until we hit a recursion error.

However that is not the case. The values that are exposed inside the hook (old and current) have their own hooks temporarily removed until the hook function has finished evaluation. This means that even if the value changes inside its own hook, no new functions are fired. The hooks are added back to the value once execution is complete, allowing it to be fired off again.

Note also that we didn't use the value x directly here. There's a subtle reason for this.

```rust
var x = 0

x::onChange((e) => {
    x += 10
})

x = 5

println(x) // Output: 5
```

Let's walk through what's happening here.

Firstly, x is being set to 5.

This triggers the hook, which injects the object `e` with these values: `{ old: 0, current: 5 }`

Then, x is being set to 15.

Once the hook has finished execution, it sets the value of x to be `e.current`, hence 5.

In the example prior to this, we set `e.current` instead, which then became the new value of x.

## Chaining Hooks

Hooks can call other hooks in a chain reaction manner:

```rust
var x = 0
var y = 0
var z = 0

x::onChange((e) => {
    y += e.current + 3
})

y::onChange((e) => {
    z = e.current / 2
})

x = 5

println(x) // 5
println(y) // 8
println(z) // 4
```

Here's the flow of the above example:

**`x = 5`**` ``->`` `**`y = 5 + 3`**` ``->`` `**`z = (5 + 3) / 2`**


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://dibs.gitbook.io/vortex-docs/language-reference/hooks.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
