

# SDK per la messaggistica client di Chat IVS - Tutorial per JavaScript, parte 2: messaggi ed eventi
<a name="chat-sdk-js-tutorial-messages-events"></a>

Questa seconda e ultima parte del tutorial è suddivisa in diverse sezioni:

1. [Sottoscrizione a eventi di messaggi di chat](#chat-js-messages-events-subscribe)

1. [Visualizzazione dei messaggi ricevuti](#chat-js-messages-events-show)

   1.  [Creazione di un componente di messaggio](#chat-js-messages-create-component)

   1. [Riconoscimento dei messaggi inviati dall'utente corrente](#chat-js-messages-recognize)

   1. [Creazione di un componente di elenco messaggi](#chat-js-messages-create-list-component)

   1. [Rendering di un elenco di messaggi di chat](#chat-js-messages-render-list)

1. [Esecuzione di azioni in una chat room](#chat-js-messages-events-room-actions)

   1. [Invio di un messaggio](#chat-js-room-actions-sending-message)

   1. [Eliminazione di un messaggio](#chat-js-room-actions-deleting-message)

1. [Fasi successive](#chat-js-messages-events-next-steps)

**Nota**: in alcuni casi, gli esempi di codice per JavaScript e TypeScript sono identici, quindi vengono combinati.

Per la documentazione completa dell'SDK, inizia con l'[SDK di messaggistica per client di chat Amazon IVS](chat-sdk.md) (qui nella *Guida per l'utente di Chat Amazon IVS*) e [Documentazione di riferimento dell'SDK di messaggistica per client di chat per JavaScript](https://aws.github.io/amazon-ivs-chat-messaging-sdk-js/latest/) su GitHub.

## Prerequisito
<a name="chat-js-messages-events-prerequisite"></a>

Assicurati di aver completato la prima parte di questo tutorial, [Chat room](chat-sdk-js-tutorial-chat-rooms.md).

## Sottoscrizione a eventi di messaggi di chat
<a name="chat-js-messages-events-subscribe"></a>

L'istanza `ChatRoom` utilizza gli eventi per comunicare quando si verificano eventi in una chat room. Per iniziare a implementare l'esperienza di chat, devi mostrare ai tuoi utenti quando altri inviano un messaggio nella stanza a cui sono connessi.

Da qui, puoi effettuare la sottoscrizione a eventi di messaggistica della chat Successivamente, ti mostreremo come aggiornare un elenco di messaggi da te creato che viene aggiornato con ogni messaggio/evento.

Nell'`App`, all'interno dell'hook `useEffect`, sottoscrivi tutti gli eventi di messaggistica:

```
// App.tsx / App.jsx

useEffect(() => {
  // ...
  const unsubscribeOnMessageReceived = room.addListener('message', (message) => {});

  return () => {
    // ...
    unsubscribeOnMessageReceived();
  };
}, []);
```

## Visualizzazione dei messaggi ricevuti
<a name="chat-js-messages-events-show"></a>

La ricezione di messaggi è una parte fondamentale dell'esperienza di chat. Utilizzando l'SDK JS Chat, puoi configurare il tuo codice per ricevere facilmente eventi da altri utenti connessi a una chat room.

Successivamente, ti mostreremo come eseguire azioni in una chat room sfruttando i componenti qui creati.

Nella tua `App`, definisci uno stato denominato `messages` con un tipo di array `ChatMessage` denominato `messages`:

------
#### [ TypeScript ]

```
// App.tsx

// ...

import { ChatRoom, ChatMessage, ConnectionState } from 'amazon-ivs-chat-messaging';

export default function App() {
  const [messages, setMessages] = useState<ChatMessage[]>([]);

  //...
}
```

------
#### [ JavaScript ]

```
// App.jsx

// ...

export default function App() {
  const [messages, setMessages] = useState([]);

  //...
}
```

------

Successivamente, nella funzione dell'ascoltatore `message`, aggiungi `message` all'array `messages`:

```
// App.jsx / App.tsx

// ...

const unsubscribeOnMessageReceived = room.addListener('message', (message) => {
  setMessages((msgs) => [...msgs, message]);
});

// ...
```

Di seguito esaminiamo le attività da completare per mostrare i messaggi ricevuti:

1.  [Creazione di un componente di messaggio](#chat-js-messages-create-component)

1. [Riconoscimento dei messaggi inviati dall'utente corrente](#chat-js-messages-recognize)

1. [Creazione di un componente di elenco messaggi](#chat-js-messages-create-list-component)

1. [Rendering di un elenco di messaggi di chat](#chat-js-messages-render-list)

### Creazione di un componente di messaggio
<a name="chat-js-messages-create-component"></a>

Il componente `Message` è responsabile della visualizzazione del contenuto di un messaggio ricevuto dalla chat room. In questa sezione, crei un componente di messaggi per il rendering di singoli messaggi di chat nell'`App`.

Crea un nuovo file nella directory `src` e chiamalo `Message`. Inserisci il tipo `ChatMessage` di questo componente e passa la stringa `content` dalle proprietà `ChatMessage` per visualizzare il testo del messaggio ricevuto dagli ascoltatori dei messaggi della chat room. Nella struttura di navigazione del progetto, passa a `Message`.

------
#### [ TypeScript ]

```
// Message.tsx

import * as React from 'react';
import { ChatMessage } from 'amazon-ivs-chat-messaging';

type Props = {
  message: ChatMessage;
}

export const Message = ({ message }: Props) => {
  return (
    <div style={{ backgroundColor: 'silver', padding: 6, borderRadius: 10, margin: 10 }}>
      <p>{message.content}</p>
    </div>
  );
};
```

------
#### [ JavaScript ]

```
// Message.jsx

import * as React from 'react';

export const Message = ({ message }) => {
  return (
    <div style={{ backgroundColor: 'silver', padding: 6, borderRadius: 10, margin: 10 }}>
      <p>{message.content}</p>
    </div>
  );
};
```

------

Suggerimento: utilizza questo componente per archiviare diverse proprietà che desideri visualizzare nelle righe dei messaggi; ad esempio, gli URL degli avatar, i nomi utente e i timestamp di quando il messaggio è stato inviato.

### Riconoscimento dei messaggi inviati dall'utente corrente
<a name="chat-js-messages-recognize"></a>

Per riconoscere il messaggio inviato dall'utente corrente, modifichiamo il codice e creiamo un contesto React per memorizzare l'`userId` dell'utente corrente.

Crea un nuovo file nella directory `src` e chiamalo `UserContext`:

------
#### [ TypeScript ]

```
// UserContext.tsx

import React, { ReactNode, useState, useContext, createContext } from 'react';

type UserContextType = {
  userId: string;
  setUserId: (userId: string) => void;
};

const UserContext = createContext<UserContextType | undefined>(undefined);

export const useUserContext = () => {
  const context = useContext(UserContext);

  if (context === undefined) {
    throw new Error('useUserContext must be within UserProvider');
  }

  return context;
};

type UserProviderType = {
  children: ReactNode;
}

export const UserProvider = ({ children }: UserProviderType) => {
  const [userId, setUserId] = useState('Mike');

  return <UserContext.Provider value={{ userId, setUserId }}>{children}</UserContext.Provider>;
};
```

------
#### [ JavaScript ]

```
// UserContext.jsx

import React, { useState, useContext, createContext } from 'react';

const UserContext = createContext(undefined);

export const useUserContext = () => {
  const context = useContext(UserContext);

  if (context === undefined) {
    throw new Error('useUserContext must be within UserProvider');
  }

  return context;
};

export const UserProvider = ({ children }) => {
  const [userId, setUserId] = useState('Mike');

  return <UserContext.Provider value={{ userId, setUserId }}>{children}</UserContext.Provider>;
};
```

------

Nota: qui abbiamo usato l'hook `useState` per memorizzare il valore `userId`. In futuro potrai utilizzare `setUserId` per modificare il contesto dell'utente o per scopi di accesso.

Quindi, sostituisci `userId` il primo parametro inviato a `tokenProvider`, utilizzando il contesto creato in precedenza:

```
// App.jsx / App.tsx

// ...

import { useUserContext } from './UserContext';

// ...


export default function App() {
  const [messages, setMessages] = useState<ChatMessage[]>([]);
  const { userId } = useUserContext();
  const [room] = useState(
    () =>
      new ChatRoom({
        regionOrUrl: process.env.REGION,
        tokenProvider: () => tokenProvider(userId, ['SEND_MESSAGE']),
      }),
  );

  // ...
}
```

Nel tuo componente `Message`, usa la variabile `UserContext` creata in precedenza, dichiara la variabile `isMine`, associa `userId` del mittente con `userId` del contesto e applica diversi stili di messaggi per l'utente corrente.

------
#### [ TypeScript ]

```
// Message.tsx

import * as React from 'react';
import { ChatMessage } from 'amazon-ivs-chat-messaging';
import { useUserContext } from './UserContext';

type Props = {
  message: ChatMessage;
}

export const Message = ({ message }: Props) => {
  const { userId } = useUserContext();

  const isMine = message.sender.userId === userId;

  return (
    <div style={{ backgroundColor: isMine ? 'lightblue' : 'silver', padding: 6, borderRadius: 10, margin: 10 }}>
      <p>{message.content}</p>
    </div>
  );
};
```

------
#### [ JavaScript ]

```
// Message.jsx

import * as React from 'react';
import { useUserContext } from './UserContext';

export const Message = ({ message }) => {
  const { userId } = useUserContext();

  const isMine = message.sender.userId === userId;

  return (
    <div style={{ backgroundColor: isMine ? 'lightblue' : 'silver', padding: 6, borderRadius: 10, margin: 10 }}>
      <p>{message.content}</p>
    </div>
  );
};
```

------

### Creazione di un componente di elenco messaggi
<a name="chat-js-messages-create-list-component"></a>

Il componente `MessageList` è responsabile della visualizzazione della conversazione di una chat room nel tempo. Il file `MessageList` è il container che contiene tutti i nostri messaggi. `Message` è una riga in `MessageList`.

Crea un nuovo file nella directory `src` e chiamalo `MessageList`. Definisci `Props` con `messages` di tipo array `ChatMessage`. All'interno del corpo, mappa la nostra proprietà `messages` e invia `Props` al componente `Message`.

------
#### [ TypeScript ]

```
// MessageList.tsx

import React from 'react';
import { ChatMessage } from 'amazon-ivs-chat-messaging';
import { Message } from './Message';

interface Props {
  messages: ChatMessage[];
}

export const MessageList = ({ messages }: Props) => {
  return (
    <div>
      {messages.map((message) => (
        <Message key={message.id} message={message}/>
      ))}
    </div>
  );
};
```

------
#### [ JavaScript ]

```
// MessageList.jsx

import React from 'react';
import { Message } from './Message';

export const MessageList = ({ messages }) => {
  return (
    <div>
      {messages.map((message) => (
        <Message key={message.id} message={message} />
      ))}
    </div>
  );
};
```

------

### Rendering di un elenco di messaggi di chat
<a name="chat-js-messages-render-list"></a>

A questo punto inserisci il nuovo `MessageList` nel tuo componente `App` principale:

```
// App.jsx / App.tsx

import { MessageList } from './MessageList';
// ...

return (
  <div style={{ display: 'flex', flexDirection: 'column', padding: 10 }}>
    <h4>Connection State: {connectionState}</h4>
    <MessageList messages={messages} />
    <div style={{ flexDirection: 'row', display: 'flex', width: '100%', backgroundColor: 'red' }}>
      <MessageInput value={messageToSend} onValueChange={setMessageToSend} />
      <SendButton disabled={isSendDisabled} onPress={onMessageSend} />
    </div>
  </div>
);

// ...
```

Ora tutti i pezzi del puzzle per l'`App` sono a posto e puoi iniziare a renderizzare i messaggi ricevuti dalla chat room. Continua di seguito per scoprire come eseguire azioni in una chat room sfruttando i componenti appena creati.

## Esecuzione di azioni in una chat room
<a name="chat-js-messages-events-room-actions"></a>

L'invio di messaggi e l'esecuzione delle azioni dei moderatori all'interno di una chat room sono alcuni dei principali modi con cui interagire in una chat room. Qui imparerai come usare vari oggetti `ChatRequest` per eseguire azioni comuni in Chatterbox, come l'invio di un messaggio, l'eliminazione di un messaggio e la disconnessione di altri utenti.

Tutte le azioni in una chat room seguono uno schema comune: per ogni azione eseguita in una chat room, esiste un oggetto di richiesta corrispondente. Per ogni richiesta è presente un oggetto di risposta corrispondente che si riceve alla conferma della richiesta.

Se ai tuoi utenti vengono concesse le autorizzazioni corrette quando crei un token di chat, possono eseguire correttamente le azioni corrispondenti utilizzando gli oggetti della richiesta per vedere quali richieste puoi eseguire in una chat room.

Di seguito, spieghiamo come [inviare un messaggio](#chat-js-room-actions-sending-message) ed [eliminare un messaggio](#chat-js-room-actions-deleting-message).

### Invio di un messaggio
<a name="chat-js-room-actions-sending-message"></a>

La classe `SendMessageRequest` consente l'invio di messaggi in una chat room. Qui puoi modificare la tua `App` per inviare una richiesta di messaggio utilizzando il componente che hai creato in [Creazione dell'input di un messaggio](chat-sdk-js-tutorial-chat-rooms.md#chat-js-rooms-message-input) (nella parte 1 di questo tutorial).

Per iniziare, definisci una nuova proprietà booleana denominata `isSending` con l'hook `useState`. Usa questa nuova proprietà per attivare lo stato disabilitato dell'elemento HTML `button` usando la costante `isSendDisabled`. Nel gestore eventi per il tuo `SendButton`, cancella il valore per `messageToSend` e imposta `isSending` su true.

*Poiché effettuerai una chiamata API da questo pulsante, l'aggiunta della proprietà booleana `isSending` consente di evitare che si verifichino più chiamate API contemporaneamente, disabilitando le interazioni utente con il `SendButton` fino al completamento della richiesta.*

```
// App.jsx / App.tsx

// ...

const [isSending, setIsSending] = useState(false);

// ...

const onMessageSend = () => {
  setIsSending(true);
  setMessageToSend('');
};

// ...

const isSendDisabled = connectionState !== 'connected' || isSending;

// ...
```

Prepara la richiesta creando una nuova istanza `SendMessageRequest` passando il contenuto del messaggio al costruttore. Dopo aver impostato gli stati `isSending` e `messageToSend`, chiama il metodo `sendMessage`, che invia la richiesta alla chat room. Infine, deseleziona il flag `isSending` quando ricevi la conferma o il rifiuto della richiesta.

------
#### [ TypeScript ]

```
// App.tsx

// ...
import { ChatMessage, ChatRoom, ConnectionState, SendMessageRequest } from 'amazon-ivs-chat-messaging'
// ...

const onMessageSend = async () => {
  const request = new SendMessageRequest(messageToSend);
  setIsSending(true);
  setMessageToSend('');

  try {
    const response = await room.sendMessage(request);
  } catch (e) {
    console.log(e);
    // handle the chat error here...
  } finally {
    setIsSending(false);
  }
};

// ...
```

------
#### [ JavaScript ]

```
// App.jsx

// ...
import { ChatRoom, SendMessageRequest } from 'amazon-ivs-chat-messaging'
// ...

const onMessageSend = async () => {
  const request = new SendMessageRequest(messageToSend);
  setIsSending(true);
  setMessageToSend('');

  try {
    const response = await room.sendMessage(request);
  } catch (e) {
    console.log(e);
    // handle the chat error here...
  } finally {
    setIsSending(false);
  }
};

// ...
```

------

Dai una chance a Chatterbox: prova a inviare un messaggio creandone una bozza con `MessageInput` e toccando quindi `SendButton`. Dovresti vedere il messaggio inviato renderizzato all'interno del `MessageList` creato in precedenza.

### Eliminazione di un messaggio
<a name="chat-js-room-actions-deleting-message"></a>

Per eliminare un messaggio da una chat room, è necessario disporre delle funzionalità adeguate. Le funzionalità vengono concesse durante l'inizializzazione del token di chat utilizzato per l'autenticazione in una chat room. Ai fini di questa sezione, `ServerApp` della sezione [Configurazione di un server di autenticazione/autorizzazione locale](chat-sdk-js-tutorial-chat-rooms.md#chat-js-rooms-auth-server) (nella parte 1 di questo tutorial) consente di specificare le funzionalità dei moderatori. Questa operazione viene eseguita nell'app utilizzando l'oggetto `tokenProvider` creato in [Creazione di un provider di token](chat-sdk-js-tutorial-chat-rooms.md#chat-js-rooms-token-provider) (anch'esso nella parte 1 del tutorial).

Qui puoi modificare il `Message` aggiungendo una funzione per eliminare il messaggio.

Innanzitutto, apri `App.tsx` e aggiungi la funzionalità `DELETE_MESSAGE` (`capabilities` è il secondo parametro della funzione `tokenProvider`).

Nota: in questo modo `ServerApp` informa le API di IVS Chat che l'utente associato al token di chat risultante può eliminare i messaggi in una chat room. In una situazione reale, probabilmente avrai una logica di backend più complessa per gestire le funzionalità degli utenti nell'infrastruttura della tua app server.

------
#### [ TypeScript ]

```
// App.tsx

// ...

const [room] = useState( () =>
    new ChatRoom({
      regionOrUrl: process.env.REGION as string,
      tokenProvider: () => tokenProvider(userId, ['SEND_MESSAGE', 'DELETE_MESSAGE']),
    }),
);

// ...
```

------
#### [ JavaScript ]

```
// App.jsx

// ...

const [room] = useState( () =>
  new ChatRoom({
    regionOrUrl: process.env.REGION,
    tokenProvider: () => tokenProvider(userId, ['SEND_MESSAGE', 'DELETE_MESSAGE']),
  }),
);

// ...
```

------

Nei passaggi successivi, aggiorni il tuo `Message` in modo da visualizzare un pulsante di eliminazione.

Apri `Message` e definisci un nuovo stato booleano denominato `isDeleting` usando l'hook `useState` con un valore iniziale di `false`. Utilizzando questo stato, aggiorna i contenuti di `Button` in modo che siano diversi a seconda dello stato corrente di `isDeleting`. Disattiva il pulsante quando `isDeleting` è true; ciò ti impedisce di provare a effettuare due richieste di eliminazione del messaggio contemporaneamente. 

------
#### [ TypeScript ]

```
// Message.tsx

import React, { useState } from 'react';
import { ChatMessage } from 'amazon-ivs-chat-messaging';
import { useUserContext } from './UserContext';

type Props = {
  message: ChatMessage;
}

export const Message = ({ message }: Props) => {
  const { userId } = useUserContext();
  const [isDeleting, setIsDeleting] = useState(false);

  const isMine = message.sender.userId === userId;

  return (
    <div style={{ backgroundColor: isMine ? 'lightblue' : 'silver', padding: 6, borderRadius: 10, margin: 10 }}>
      <p>{message.content}</p>
      <button disabled={isDeleting}>Delete</button>
    </div>
  );
};
```

------
#### [ JavaScript ]

```
// Message.jsx

import React from 'react';
import { useUserContext } from './UserContext';

export const Message = ({ message }) => {
  const { userId } = useUserContext();
  const [isDeleting, setIsDeleting] = useState(false);

  return (
    <div style={{ backgroundColor: isMine ? 'lightblue' : 'silver', padding: 6, borderRadius: 10, margin: 10 }}>
      <p>{message.content}</p>
      <button disabled={isDeleting}>Delete</button>
    </div>
  );
};
```

------

Definisci una nuova funzione chiamata `onDelete` che accetta una stringa come uno dei suoi parametri e restituisce `Promise`. Nel corpo di chiusura dell'azione di `Button`, utilizza `setIsDeleting` per attivare la proprietà booleana `isDeleting` prima e dopo una chiamata a `onDelete`. Per il parametro string, inserisci l'ID del messaggio del componente.

------
#### [ TypeScript ]

```
// Message.tsx

import React, { useState } from 'react';
import { ChatMessage } from 'amazon-ivs-chat-messaging';
import { useUserContext } from './UserContext';

export type Props = {
  message: ChatMessage;
  onDelete(id: string): Promise<void>;
};

export const Message = ({ message onDelete }: Props) => {
  const { userId } = useUserContext();
  const [isDeleting, setIsDeleting] = useState(false);
  const isMine = message.sender.userId === userId;
  const handleDelete = async () => {
    setIsDeleting(true);
    try {
      await onDelete(message.id);
    } catch (e) {
      console.log(e);
      // handle chat error here...
    } finally {
      setIsDeleting(false);
    }
  };

  return (
    <div style={{ backgroundColor: isMine ? 'lightblue' : 'silver', padding: 6, borderRadius: 10, margin: 10 }}>
      <p>{content}</p>
      <button onClick={handleDelete} disabled={isDeleting}>
        Delete
      </button>
    </div>
  );
};
```

------
#### [ JavaScript ]

```
// Message.jsx

import React, { useState } from 'react';
import { useUserContext } from './UserContext';

export const Message = ({ message, onDelete }) => {
  const { userId } = useUserContext();
  const [isDeleting, setIsDeleting] = useState(false);
  const isMine = message.sender.userId === userId;
  const handleDelete = async () => {
    setIsDeleting(true);
    try {
      await onDelete(message.id);
    } catch (e) {
      console.log(e);
      // handle the exceptions here...
    } finally {
      setIsDeleting(false);
    }
  };

  return (
    <div style={{ backgroundColor: 'silver', padding: 6, borderRadius: 10, margin: 10 }}>
      <p>{message.content}</p>
      <button onClick={handleDelete} disabled={isDeleting}>
        Delete
      </button>
    </div>
  );
};
```

------

Successivamente, aggiorna il `MessageList` per riflettere le ultime modifiche apportate al componente `Message`.

Apri `MessageList` e definisci una nuova funzione chiamata `onDelete` che accetta una stringa come parametro e restituisce `Promise`. Aggiorna il `Message` e passalo attraverso le proprietà di `Message`. Il parametro string nella nuova chiusura sarà l'ID del messaggio che desideri eliminare, che viene passato dal tuo `Message`.

------
#### [ TypeScript ]

```
// MessageList.tsx

import * as React from 'react';
import { ChatMessage } from 'amazon-ivs-chat-messaging';
import { Message } from './Message';

interface Props {
  messages: ChatMessage[];
  onDelete(id: string): Promise<void>;
}

export const MessageList = ({ messages, onDelete }: Props) => {
  return (
    <>
      {messages.map((message) => (
        <Message key={message.id} onDelete={onDelete} content={message.content} id={message.id} />
      ))}
    </>
  );
};
```

------
#### [ JavaScript ]

```
// MessageList.jsx

import * as React from 'react';
import { Message } from './Message';

export const MessageList = ({ messages, onDelete }) => {
  return (
    <>
      {messages.map((message) => (
        <Message key={message.id} onDelete={onDelete} content={message.content} id={message.id} />
      ))}
    </>
  );
};
```

------

Successivamente, aggiorna il `App` per riflettere le ultime modifiche apportate al `MessageList`.

Quindi, in `App` definisci una funzione denominata `onDeleteMessage` e passala alla proprietà `MessageList onDelete`.

------
#### [ TypeScript ]

```
// App.tsx

// ...

const onDeleteMessage = async (id: string) => {};

return (
  <div style={{ display: 'flex', flexDirection: 'column', padding: 10 }}>
    <h4>Connection State: {connectionState}</h4>
    <MessageList onDelete={onDeleteMessage} messages={messages} />
    <div style={{ flexDirection: 'row', display: 'flex', width: '100%' }}>
      <MessageInput value={messageToSend} onMessageChange={setMessageToSend} />
      <SendButton disabled={isSendDisabled} onSendPress={onMessageSend} />
    </div>
  </div>
);

// ...
```

------
#### [ JavaScript ]

```
// App.jsx

// ...

const onDeleteMessage = async (id) => {};

return (
  <div style={{ display: 'flex', flexDirection: 'column', padding: 10 }}>
    <h4>Connection State: {connectionState}</h4>
    <MessageList onDelete={onDeleteMessage} messages={messages} />
    <div style={{ flexDirection: 'row', display: 'flex', width: '100%' }}>
      <MessageInput value={messageToSend} onMessageChange={setMessageToSend} />
      <SendButton disabled={isSendDisabled} onSendPress={onMessageSend} />
    </div>
  </div>
);

// ...
```

------

Prepara una richiesta creando una nuova istanza di `DeleteMessageRequest`, passando l'ID messaggio pertinente al parametro del costruttore e una chiamata `deleteMessage` che accetti la richiesta preparata sopra:

------
#### [ TypeScript ]

```
// App.tsx

// ...

const onDeleteMessage = async (id: string) => {
  const request = new DeleteMessageRequest(id);
  await room.deleteMessage(request);
};

// ...
```

------
#### [ JavaScript ]

```
// App.jsx

// ...

const onDeleteMessage = async (id) => {
  const request = new DeleteMessageRequest(id);
  await room.deleteMessage(request);
};

// ...
```

------

Successivamente, aggiorna lo stato di `messages` in modo che rifletta un nuovo elenco di messaggi che omette il messaggio appena eliminato.

Nell'hook `useEffect`, ascolta l'evento `messageDelete` e aggiorna il tuo array di stato `messages` eliminando il messaggio con un ID corrispondente al parametro `message`.

Nota: l'evento `messageDelete` potrebbe essere generato quando i messaggi vengono eliminati dall'utente corrente o da qualsiasi altro utente presente nella stanza. Gestirlo nel gestore eventi (anziché accanto alla richiesta `deleteMessage`) consente di unificare la gestione dell'eliminazione dei messaggi.

```
// App.jsx / App.tsx

// ...

const unsubscribeOnMessageDeleted = room.addListener('messageDelete', (deleteMessageEvent) => {
  setMessages((prev) => prev.filter((message) => message.id !== deleteMessageEvent.id));
});

return () => {
  // ...

  unsubscribeOnMessageDeleted();
};

// ...
```

A questo punto puoi eliminare gli utenti da una chat room nella tua app di chat.

## Fasi successive
<a name="chat-js-messages-events-next-steps"></a>

Come esperimento, prova a implementare altre azioni in una stanza, ad esempio la disconnessione di un altro utente.