# Subscrever-se a Alterações

Uma maneira elegante de escrever seu código é assinar eventos e executar uma função sempre que esse evento ocorrer.

Vários [Event listeners](https://github.com/decentraland/docs/blob/main/creator/sdk7/interactivity/event-listeners.md) vêm pré-definidos como parte do SDK, mas você também pode usar o `onChange()` método em qualquer componente para alcançar o mesmo. Isso também funciona com qualquer [Componente Personalizado](https://github.com/decentraland/docs/blob/main/creator/sdk7/architecture/custom-components.md) que você definiu, sem necessidade de trabalho extra.

Por exemplo, a função a seguir verifica o componente `AvatarEquippedData` no player entity, e executa uma função se o player alterar qualquer um de seus wearables ou emotes equipados. Os novos valores do componente são passados como argumentos da função.

```ts
import { AvatarEquippedData } from '@dcl/sdk/ecs'

export function main() {
	AvatarEquippedData.onChange(engine.PlayerEntity, (equipped) => {
		if (!equipped) return
		console.log('New wearables list: ', equipped.wearableUrns)
		console.log('New emotes list : ', equipped.emoteUrns)
	})
}
```

Graças ao `onChange()` método, não é necessário criar um system e verificar iterativamente por novos valores a cada frame; isso simplifica bastante esse caso de uso muito comum.

{% hint style="warning" %}
**📔 Nota**: Não use `onChange()` dentro de um System, pois isso assinaria uma nova cópia da função a cada frame do game loop, e poderia potencialmente causar crashes.
{% endhint %}

O mesmo método funciona imediatamente com [Componente Personalizado](https://github.com/decentraland/docs/blob/main/creator/sdk7/architecture/custom-components.md). Por exemplo:

```ts
// definir componente
export const MyComponent = engine.defineComponent('myComponent', {
	value1: Schemas.Boolean,
	value2: Schemas.Float,
})

// Uso
export function main() {
	// Criar entidades
	const myEntity = engine.addEntity()

	// Criar instâncias do componente
	MyComponent.create(myEntity, {
		value1: true,
		value2: 10,
	})

	// Assinar alterações
	MyComponent.onChange(myEntity, (componentData) => {
		if (!componentData) return
		console.log(componentData.value1)
		console.log(componentData.value2)
	})
}
```

Você também pode combinar essa abordagem com [Consultando componentes](https://github.com/decentraland/docs/blob/main/creator/sdk7/architecture/querying-components.md), para assinar em massa cada entity na cena que tenha determinado componente em sua própria função.

```ts
export function main() {
	for (const [entity] of engine.getEntitiesWith(MyComponent)) {
		MyComponent.onChange(entity, (componentData) => {
			if (!componentData) return
			console.log(componentData.value1)
			console.log(componentData.value2)
		})
	}
}
```

Note que essa abordagem só irá assinar `onChange()` para entidades que existam no início da cena, por exemplo entidades criadas via a UI do [Creator Hub](https://github.com/decentraland/docs/blob/main/creator/scene-editor/get-started/about-editor.md).

{% hint style="info" %}
**💡 Tip**: Se você preferir lidar com eventos que não estejam necessariamente relacionados à alteração de um componente, recomendamos importar a biblioteca TypeScript [Mitt](https://www.npmjs.com/package/mitt) para sua cena. Essa biblioteca oferece funções simples para emitir e escutar eventos.
{% endhint %}
