
Utilisation de composants web dans une application React
Temps de lecture : 15 minutes
Dans un article précédentnous avons montré comment créer et publier un composant Web.
Il est maintenant temps de voir comment utiliser une des principales fonctionnalités des composants Web :
Les composants personnalisés et les widgets construits sur la base des normes des composants Web fonctionneront dans les navigateurs modernes et pourront être utilisés avec n'importe quelle bibliothèque JavaScript ou framework qui fonctionne avec HTML.
Dans ce billet, nous allons voir comment les composants Web peuvent être intégrés dans un environnement React .
Compte API Vonage
Vonage API Account
To complete this tutorial, you will need a Vonage API account. If you don’t have one already, you can sign up today and start building with free credit. Once you have an account, you can find your API Key and API Secret at the top of the Vonage API Dashboard.
This tutorial also uses a virtual phone number. To purchase one, go to Numbers > Buy Numbers and search for one that meets your needs.
Composants Web
Tout d'abord, examinons les composants Web qui seront utilisés dans l'application.
Nous avons le composant clavier du billet précédent et un composant de liste de contacts. La liste de contacts peut enregistrer et charger les noms et les numéros de téléphone des personnes appelées à partir du stockage local du navigateur. Le composant Web peut également transmettre le numéro de téléphone d'un contact à l'application sous la forme d'un événement personnalisé lorsqu'il est cliqué.
Il existe également une boîte de dialogue Boîte de dialogue du composant Web matériel qui s'affichera après la fin d'un appel si le numéro n'est pas déjà dans les contacts, afin qu'il puisse être enregistré.

Enjeux
Pour voir quels obstacles nous pouvons rencontrer lors de l'utilisation de ces Applications Web dans une application React, nous allons référencer les éléments suivants. Des éléments personnalisés partout.
Ils ont pris la noble responsabilité de "S'assurer que les frameworks et les éléments personnalisés peuvent être BFFs 🍻".
Pour ce faire, nous prenons des frameworks/bibliothèques, nous les soumettons à différents tests et nous établissons un rapport sur la manière dont ils s'intègrent aux composants Web.
Comment React se positionne-t-il ? À la date de publication de ce billet, voici les résultats :

La situation n'est pas brillante, mais nous pouvons la faire fonctionner. Jetons un coup d'œil à certains problèmes.
L'un des moyens de transmettre des données à votre composant Web est d'utiliser des propriétés :
<dwanes-keypad actionText="Call" cancelText="Hang up"></dwanes-keypad>
Lorsque cela est fait dans une Application React, les données sont stringifiées. Ainsi, les tableaux (ie [1,2,3,4]) se transformeront en "1,2,3,4" et les objets (ie {"key1":value1, "key2":value2}) deviendront le redoutable "[object Object]".
Un autre problème est la façon dont React gère les événements.
React a son SyntheticEvent qui est une enveloppe autour de l'événement natif d'un navigateur. Les conclusions de Custom Elements Everywhere montrent que le SyntheticEvent de React "ne peut pas écouter les événements DOM provenant des Custom Elements". Ils fournissent également une solution que nous allons voir par la suite.
Solutions
Maintenant que nous savons ce qui nous attend, travaillons à surmonter ces problèmes.
L'objectif est de créer un composant React "App" de base et de placer nos composants Web à l'intérieur.
Il existe deux façons d'écrire des composants dans une application React - en tant que Classe ou Fonction.
Auparavant, le fait de devoir utiliser "State" dans votre composant était un facteur déterminant pour l'utilisation d'un composant de classe. composant de classe plutôt qu'un composant de fonction.
Puis dans React 16.8, Hooks Ils vous permettent d'utiliser l'état et d'autres fonctionnalités de React sans écrire de classe.
Ainsi, pour être le plus exhaustif possible dans ce post, nous inclurons les composants Web dans les applications React qui sont créées à l'aide de composants de classe et de composants de fonction avec des Hooks.
Comme à chaque fois que des composants Web sont utilisés, ils doivent être inclus dans le projet. Vous pouvez soit les installer, soit créer un lien vers eux à partir d'un CDN. (Ce point a été abordé dans le article précédent.)
Pour cette intégration, nous utiliserons un CDN.
Dans l'étiquette <head> de public\index.html dans le code d'exemple, vous trouverez :
<!-- Web Component polyfill -->
<script src="https://unpkg.com/@webcomponents/webcomponentsjs@latest/webcomponents-loader.js"></script>
<!-- Load the Web Components -->
<script type="module" src="https://unpkg.com/@material/mwc-dialog@canary/mwc-dialog?module"></script>
<script type="module" src="https://unpkg.com/@dwane-vonage/dwanes-keypad@latest/dwanes-keypad.js?module"></script>
<script type="module" src="https://unpkg.com/@dwane-vonage/dwanes-contacts@latest/dwanes-contacts.js?module"></script> Composante de la classe
Vous pouvez trouver l'exemple de code dans ce projet Glitch.
Note : J'ai remixé le Modèle de démarrage Glitch React.
Gestion des événements
Pour pouvoir gérer les événements provenant d'un composant Web, nous devons d'abord obtenir une référence à celui-ci afin que React sache qu'il existe et puisse ajouter un écouteur d'événements. Dans la fonction src\App.js render, vous trouverez quelques ref tags :
<main>
<section>
<dwanes-keypad actionText="Call" cancelText="Hang up" ref="keypad"></dwanes-keypad>
<div id="status">{this.state.callStatus}</div>
</section>
<dwanes-contacts ref="contacts"></dwanes-contacts>
</main>
<mwc-dialog id="dialog" heading="Contacts" ref="dialog">
<p>Save <span id="number-to-save">{this.state.numberToSave}</span> to contacts?</p>
<mwc-textfield
id="text-field"
minlength="3"
maxlength="64"
placeholder="First name"
dialogInitialFocus
required
ref="firstName">
</mwc-textfield>
<mwc-button
id="primary-action-button"
slot="primaryAction"
onClick={this.handleSaveContact}>
Confirm
</mwc-button>
<mwc-button
slot="secondaryAction"
dialogAction="close">
Cancel
</mwc-button>
</mwc-dialog>
Les balises ref indiquent à React qu'il doit prêter attention à ces éléments.
Dans le componentDidMount() dans src\App.jsles auditeurs d'événements sont ajoutés aux références d'éléments que nous venons de mettre en place. Voici le code :
this.refs.contacts.addEventListener('contacts-loaded', (event) => {
contacts = event.detail.contacts;
console.log('contacts-loaded: ', contacts);
});
this.refs.contacts.addEventListener('contact-selected', (event) => {
this.refs.keypad.setDigits(event.detail.contact.phone);
});
this.refs.keypad.addEventListener('action-ended', () => {
this.setState({callStatus: "Call has ended."});
const contactFound = contacts.find(contact => contact.phone === this.state.numberToSave);
if (contactFound){
console.log('Number already in contacts')
} else {
this.refs.dialog.show();
}
});
this.refs.keypad.addEventListener('digits-sent', event => {
if (event.detail.digits !== ""){
this.refs.keypad.createAction();
this.setState({callStatus: "Call is being made", numberToSave:event.detail.digits});
} else {
this.setState({callStatus: "Please enter a phone number."});
}
});
this.refs.keypad.addEventListener("digit-added", event => {
console.log('digit-added: ', event.detail.digit);
});
Traitement des données
Pour notre composant clavier, nous passons des chaînes dans les propriétés, donc rien de spécial ne doit être fait avec ces données dans React.
Lors de l'enregistrement du contact après un appel, les données sont des objets :
{name:this.refs.firstName.value, phone:this.state.numberToSave}Elle est transmise à une méthode du composant Web de la liste des contacts :
this.refs.contacts.saveContact({name:this.refs.firstName.value, phone:this.state.numberToSave});Si le composant liste de contacts n'utilisait pas l'objet pour manipuler les données et les enregistrer dans le stockage local, nous pourrions passer l'objet comme suit :
this.refs.contacts.contactProp = {name:this.refs.firstName.value, phone:this.state.numberToSave};Il en va de même pour les tableaux.
Remarque importante ! L'API utilisée pour obtenir la référence aux composants Web est considérée comme ancienne et est "susceptible d'être supprimée dans l'une des prochaines versions". documentation contient plus d'informations et propose des alternatives.
Montrons l'une des alternatives mentionnées.
Si vous utilisez React 16.3 ou une version ultérieure, voici le projet Glitch exemple de code en utilisant React.createRef().
C'est à peu près la même idée, mais avec plus de syntaxe. Vous créez la référence avec React.createRef() dans le constructeur :
this.contacts = React.createRef();Attachez-la au composant Web dans la section render:
<dwanes-contacts ref={this.contacts}></dwanes-contacts>
Ajouter un écouteur d'événement dans componentDidMount():
this.contacts.current.addEventListener('contact-selected', (event) => {
this.keypad.current.setDigits(event.detail.contact.phone);
});
Appeler une méthode d'un composant Web :
this.contacts.current.saveContact({name:this.firstName.current.value, phone:this.state.numberToSave});Transmettre des données "riches" au composant Web :
this.contacts.current.contactProp = {name:this.firstName.current.value, phone:this.state.numberToSave};
this.contacts.current.arrayProp = [value1, value2, value3]; Composant de fonction avec crochets
Maintenant, pour la nouvelle façon, à partir de React 16.8, qui peut être utilisée pour créer une référence de composant Web.
La plupart des tâches lourdes sont gérées par les Hooks. Qu'il s'agisse de gérer l'état, les effets de bord ou les références DOM, il y a probablement un Hook que vous pouvez utiliser.
Si ce n'est pas le cas, vous pouvez créer un crochet personnalisé.
Dans ce cas, l'un des crochets que nous utiliserons est useRef.
Cela ressemblera beaucoup à l'exemple React.createRef() exemple.
Vous pouvez trouver l'exemple de code Function Component with Hooks dans ce projet Glitch.
Gestion des événements
Tout d'abord, nous devons initialiser les références de chaque composant Web. C'est ce que nous faisons avec ce code :
const keypad = useRef(null);
const dialog = useRef(null);
const contactsEl = useRef(null);
const firstName = useRef(null);null est la valeur initiale de la référence.
Ensuite, dans la section de retour, nous attachons les références aux composants Web avec la balise ref={referenceName}.
Voici le code :
<main>
<section>
<dwanes-keypad actionText="Call" cancelText="Hang up" ref={keypad}></dwanes-keypad>
<div id="status">{callStatus}</div>
</section>
<dwanes-contacts ref={contactsEl}></dwanes-contacts>
</main>
<mwc-dialog id="dialog" heading="Contacts" ref={dialog}>
<p>Save <span id="number-to-save">{numberToSave}</span> to contacts?</p>
<mwc-textfield
id="text-field"
minlength="3"
maxlength="64"
placeholder="First name"
dialogInitialFocus
required
ref={firstName}>
</mwc-textfield>
<mwc-button
id="primary-action-button"
slot="primaryAction"
onClick={handleSaveContact}>
Confirm
</mwc-button>
<mwc-button
slot="secondaryAction"
dialogAction="close">
Cancel
</mwc-button>
</mwc-dialog>
Ajoutons maintenant nos récepteurs d'événements.
Pour ce faire, nous les placerons dans un crochet de type useEffect Hook:
useEffect(()=> {
contactsEl.current.addEventListener('contacts-loaded', handleContactsLoaded);
contactsEl.current.addEventListener('contact-selected', handleContactSelected);
keypad.current.addEventListener('digit-added', handleDigitAdded);
keypad.current.addEventListener('digits-sent', handleDigitsSent);
keypad.current.addEventListener('action-ended', handleActionEnded);
return () => {
contactsEl.current.removeEventListener('contacts-loaded', handleContactsLoaded);
contactsEl.current.removeEventListener('contact-selected', handleContactSelected);
keypad.current.removeEventListener('digit-added', handleDigitAdded);
keypad.current.removeEventListener('digits-sent', handleDigitsSent);
keypad.current.removeEventListener('action-ended', handleActionEnded);
};
});
Traitement des données
Comme nous l'avons déjà mentionné, ce code ressemblera beaucoup à l'exemple de code React.createRef() exemple de code.
Utilisation de la méthode d'un composant Web pour envoyer des données :
contactsEl.current.saveContact({name:firstName.current.value, phone:numberToSave});Pour transmettre des données "riches" au composant Web :
contactsEl.current.contactProp = {name:this.firstName.current.value, phone:this.state.numberToSave};
contactsEl.current.arrayProp = [value1, value2, value3]; Passer un appel
Nous avons accroché nos Web Components, pourquoi ne pas passer un appel avec notre application React ?
Les étapes ci-dessous sont une version modifiée et un aperçu rapide de notre tutoriel sur la création d'un appel vocal in-app. tutoriel pour utiliser nos composants Web.
Vous pouvez vous y référer pour plus de détails.
Pour le faire fonctionner, il faut
L'interface de programmation Nexmo
Un Account GitHub
Étape 1 : Remixer ce projet Glitch.
Cela permettra non seulement de configurer l'application React avec les Web Components, mais aussi d'installer le Client SDK Nexmo qui sera utilisé pour passer l'appel téléphonique.
Etape 2 : Installer l'outil CLI de Nexmo : Installer l'outil Nexmo CLI.
Dans votre terminal, tapez :
Obtenez votre clé d'API de développeur Vonage et votre secret d'API à partir de votre tableau de bord.
Exécutez la commande suivante dans un terminal, en remplaçant api_key et api_secret par les vôtres :
Étape 3 : Créer un OCNI.
Assurez-vous d'être connecté à GitHub puis allez sur https://gist.github.com .
Entrer ncco.json dans "Nom de fichier, y compris l'extension".
Copiez et collez l'objet JSON suivant dans le gist :
[
{
"action": "talk",
"text": "Please wait while we connect you."
},
{
"action": "connect",
"endpoint": [
{
"type": "phone",
"number": "PHONE_NUMBER"
}
]
}
]Remplacer PHONE_NUMBER par votre numéro de téléphone. Les numéros Numbers sont au format E.164, les "+" et "-" ne sont pas valables. Veillez à préciser l'indicatif de votre pays lorsque vous saisissez votre numéro, par exemple, US : 14155550100 et UK : 447700900001.
Cliquez sur le bouton Create secret gist sur le bouton
Cliquez sur le bouton Raw sur le bouton
Notez l'URL qui s'affiche dans votre navigateur, vous l'utiliserez à l'étape suivante.
Étape 4 : Créer une application Nexmo
Créez votre répertoire de projet si vous ne l'avez pas encore fait.
Allez dans le répertoire du projet.
Créez une application Nexmo en copiant et en collant la commande ci-dessous dans le terminal :
Veillez à modifier la valeur de l'argument
--voice-answer-urlen remplaçantGIST-URLpar l'URL gist de l'étape précédente.
Un fichier nommé .nexmo-app est créé dans le répertoire de votre projet et contient l'identifiant de l'application Nexmo nouvellement créée et la clé privée. Un fichier de clé privée nommé private.key est également créé.
Veuillez noter l'identifiant de l'application car vous en aurez besoin à l'avenir.
Étape 5 : Créer un utilisateur
Créez un utilisateur nommé Alice à l'aide de la commande suivante dans l'interface de commande Nexmo :
Cela renverra un identifiant similaire à celui qui suit :
User created: USR-aaaaaaaa-bbbb-cccc-dddd-0123456789ab
Étape 6 : Générer un JWT
Générez un JWT à l'aide de la CLI Nexmo en exécutant la commande suivante, mais n'oubliez pas de remplacer la variable APP_ID par votre propre valeur :
Le JWT généré sera valide pour les 6 prochaines heures.
Copiez et collez le JWT dans le fichier de projet src/App.js dans le fichier du projet Glitch, à l'endroit où il est indiqué "PASTE ALICE JWT HERE".
Étape 7 : Appelez vous-même !
Composez votre numéro sur le clavier et appuyez sur APPEL.
Si tout a fonctionné correctement, votre téléphone devrait recevoir un appel. Une fois l'appel terminé, une boîte de dialogue doit apparaître pour vous demander si vous souhaitez enregistrer le numéro.
Remarque : le NCCO étant codé en dur avec votre numéro de téléphone, votre numéro sera appelé, quelle que soit la manière dont vous l'avez tapé au clavier. Pour générer dynamiquement le NCCO, il faudra le faire en amont.
Voilà, c'est fait ! Nous avons maintenant utilisé les composants Web dans une application React.
Cela a-t-il fonctionné ? C'était cool ?
Comme pour tout ce qui concerne le codage, il existe de multiples façons de faire les choses.
J'ai trouvé un autre moyen dans la base de données React et Stencil JS est d'envelopper vos composants Web dans des composants React.
Avez-vous procédé de cette manière ou peut-être d'une autre manière ? Nous aimerions vraiment en savoir plus sur ce sujet ou sur tout autre commentaire ou question dans notre canal Slack de la communauté.
