Une plongée à froid dans React Native (tutoriel pour débutants)

Publié: 2022-03-11

Lorsque React Native a été annoncé, les premières réactions ont été extrêmement positives. Traditionnellement, lorsque nous pensons aux technologies Web dans l'espace mobile, des choses comme Apache Cordova nous viennent à l'esprit, qui nous permettent de regrouper des sites Web ou des applications Web en tant qu'applications pour plates-formes mobiles. Dans ce didacticiel pour débutants, nous examinerons l'architecture de React Native, la philosophie derrière React Native et en quoi elle diffère des autres solutions dans le même espace. A la fin de l'article, nous aurons transformé une application React « Hello World » en une application React Native.

Commençons par dire que React Native est une technologie relativement nouvelle. Il est officiellement disponible depuis mars 2015, après avoir été en version bêta privée depuis le début de cette année, et utilisé en interne sur Facebook pendant un certain temps auparavant. Le dicton « Rome ne s'est pas construite en un jour » s'applique généralement aussi à la technologie. Des outils comme grunt et des plateformes comme Node.js ont mis des années à mûrir. Dans le monde du Web, les choses évoluent rapidement, et avec un grand nombre de frameworks, de packages et d'outils qui sortent chaque jour, les développeurs ont tendance à devenir un peu plus sceptiques et ne veulent pas sauter dans tous les trains à la mode pour se rendre compte que ils se sont retrouvés dans une situation de verrouillage du fournisseur. Nous verrons ce qui rend React Native spécial, pourquoi c'est une technologie qui vaut la peine d'être abordée, et couvrirons quelques cas où ce ne sont pas tous des licornes et des arcs-en-ciel.

Sous la capuche

Lorsqu'on parle de technologies Web sur mobile, les solutions disponibles entrent généralement dans l'une des catégories suivantes.

Regroupement d'applications Web dans un navigateur Web mobile

L'application Web réside dans un navigateur mobile, généralement appelé WebView. Sans aucune refactorisation majeure, un site Web ou une application Web fonctionne sur l'appareil mobile. Nous devrons peut-être prendre en compte les événements du navigateur mobile tels que le tapotement ou l'écoute des changements d'orientation de l'appareil et le plus petit écran pour une expérience utilisateur complète, mais nous avons une version mobile fonctionnelle avec un minimum d'effort. Cordova/PhoneGap est l'option la plus populaire dans cette catégorie. Malheureusement, cette option présente un gros inconvénient : dans certains cas, les applications développées à l'aide de Cordova sont nettement plus lentes que les applications natives, en particulier pour les applications à forte charge graphique. Dans d'autres cas, le système d'exploitation mobile ne fournit pas toutes les fonctionnalités de WebView disponibles dans le navigateur mobile. L'expérience utilisateur peut également différer des applications natives ; cela peut se produire en raison de l'application ou de la plate-forme elle-même. Ce problème peut aller de barres de défilement ne se sentant pas de la même manière à un retard notable lorsque vous appuyez sur des éléments.

Compilation vers les technologies natives

Une solution complètement différente consiste à créer une base de code native à la fin. Cela se produit en transformant le code source d'origine dans un autre langage de programmation. Nous échangeons les performances natives contre une couche d'abstraction avec quelques incertitudes. Dans le cas des solutions fermées, nous ne savons même pas ce qui se passe sous le capot et à quel type de boîte noire nous avons affaire. Dans d'autres cas, nous ne savons pas dans quelle mesure la prochaine mise à jour du système d'exploitation mobile cassera notre code et quand des correctifs ou des mises à jour seront disponibles. Un exemple populaire de cette catégorie serait Haxe.

Utiliser une couche JavaScript

Ici, nous utilisons le moteur JavaScript de l'environnement mobile et y exécutons notre JavaScript. Les contrôles natifs sont mappés sur des objets et des fonctions JavaScript. Ainsi, lorsque nous devions appeler une fonction appelée fancyButtonRightHere() , un bouton apparaissait à l'écran. NativeScript ou Appcelerator Titanium sont des exemples bien connus de cette catégorie.

React Native pourrait être classé dans la troisième catégorie. Pour les versions iOS et Android, React Native utilise JavaScriptCore sous le capot, qui est le moteur JavaScript par défaut sur iOS. JavaScriptCore est également le moteur JavaScript des navigateurs Safari d'Apple. Les développeurs OS X et iOS peuvent en fait s'interfacer directement avec lui s'ils le souhaitent.

Une grande différence est que React Native exécute le code JavaScript dans un thread séparé, de sorte que l'interface utilisateur ne se bloque pas et que les animations doivent être soyeuses et fluides.

React est la fonctionnalité clé

Il convient de noter que le "React" dans React Native n'est pas mis là par accident. Pour React Native, nous avons besoin de comprendre exactement ce que propose React. Les concepts suivants fonctionnent de la même manière dans React et React Native, bien que ces exemples de code soient conçus pour être exécutés dans le navigateur.

Point d'entrée de rendu unique

Lorsque nous examinons un composant React simple, la première chose que nous pouvons remarquer est que le composant a une fonction de render . En fait, React génère une erreur s'il n'y a pas de fonction de rendu définie dans le composant.

 var MyComponent = function() { this.render = function() { // Render something here }; };

La particularité est que nous ne manipulons pas les éléments DOM ici, mais nous renvoyons une construction basée sur XML qui représente ce qui sera rendu dans le DOM. Cette construction basée sur XML est appelée JSX.

 var MyComponent = function() { this.render = function() { return <div className="my-component">Hello there</div>; }; };

Un transformateur JSX spécial prend tout ce code d'apparence XML et le convertit en fonctions. Voici à quoi ressemblera le composant après la transformation :

 var MyComponent = function() { this.render = function() { return React.createElement("div", { className: "my-component" }, "Hello there"); }; };

Le plus grand avantage est qu'en jetant un coup d'œil rapide au composant, nous savons toujours ce qu'il est censé faire. Par exemple, un <FriendList /> peut restituer un certain nombre de composants <Friend /> . Nous ne pouvons rendre nos composants nulle part ailleurs que dans la fonction de render , il n'y a donc jamais de souci que nous ne sachions pas exactement d'où vient notre composant rendu.

Flux de données unidirectionnel

Pour construire le contenu d'un composant, React fournit des propriétés ou des accessoires en abrégé. Semblable aux attributs XML, nous transmettons les accessoires directement à un composant et pouvons ensuite utiliser les accessoires à l'intérieur du composant construit.

 var Hello = function(props) { this.render = function() { return <div className="my-component">Hello {props.name}</div>; }; }; var Greeter = function() { this.render = function() { return <Hello name="there" /> } };

Cela conduit à ce que nos composants soient dans une structure arborescente, et nous ne sommes autorisés à transmettre des données que lors de la construction d'éléments enfants.

Re-rendre sur les changements

En plus des accessoires, les composants peuvent également avoir un état interne. L'exemple le plus frappant de ce comportement serait un compteur de clics qui met à jour sa valeur lorsqu'un bouton est enfoncé. Le nombre de clics lui-même serait enregistré dans l'état.

Chacun des changements d'accessoire et d'état déclenche un nouveau rendu complet du composant.

DOM virtuel

Maintenant, quand tout est restitué lorsque les accessoires ou l'état changent, comment se fait-il que React lui-même fonctionne si bien ? L'ingrédient magique est le "DOM virtuel". Chaque fois que quelque chose doit être rendu à nouveau, une représentation virtuelle du DOM mis à jour est générée. Le DOM virtuel se compose de représentations légères d'éléments modélisés d'après l'arborescence des composants, ce qui rend le processus de génération beaucoup plus efficace que la génération d'éléments DOM réels. Avant d'appliquer les modifications au DOM réel, des vérifications sont effectuées pour déterminer où exactement dans l'arborescence des composants les modifications se sont produites, un diff est créé et seules ces modifications spécifiques sont appliquées.

Premiers pas avec ce tutoriel React Native

Il y a certaines conditions préalables que les débutants devront mettre en place afin de développer pour React Native. Étant donné qu'iOS a été la première plate-forme prise en charge, et celle que nous couvrons dans ce didacticiel, nous avons besoin de macOS et Xcode, au moins la version 6.3. Node.js est également nécessaire. Ce qui aide, c'est d'installer Watchman via le gestionnaire de packages Brew avec brew install watchman . Bien que cela ne soit pas nécessairement nécessaire, cela aide à gérer de nombreux fichiers dans notre projet React Native.

React Native : le cadre de développement d'applications mobiles le plus sain.
Tweeter

Pour installer React Native, il suffit d'installer l'application en ligne de commande React Native avec npm install -g react-native-cli . L'appel de la commande react-native nous aide ensuite à créer une nouvelle application React Native. L'exécution react-native init HelloWorld crée un dossier appelé HelloWorld dans lequel le code passe-partout peut être trouvé.

Animation de terminal montrant comment configurer une application React Native "Hello World".

Transformer une application React

React étant la fonctionnalité clé et les principes de base issus de la bibliothèque React, examinons ce dont nous avons besoin pour transformer une application React "Hello World" minimale en une application React Native.

Nous utilisons certaines fonctionnalités ES2015 dans cet exemple de code, en particulier les classes. Il est tout à fait possible de s'en tenir à React.createClass ou d'utiliser un formulaire de fonction similaire au modèle de module populaire.

 var React = require('react'); class HelloThere extends React.Component { clickMe() { alert('Hi!'); } render() { return ( <div className="box" onClick={this.clickMe.bind(this)}>Hello {this.props.name}. Please click me.</div> ); } } React.render(<HelloThere name="Component" />, document.getElementById('content'));

Étape 1 : adopter les modules CommonJS

Dans la première étape, nous devons modifier le fait que le module React doit utiliser react-native à la place.

 var React = require('react-native'); class HelloThere extends React.Component { clickMe() { alert('Hi!'); } render() { return ( <div className="box" onClick={this.clickMe.bind(this)}>Hello {this.props.name}. Please click me.</div> ); } } React.render(<HelloThere name="Component" />, document.getElementById('content'));

Ce qui fait généralement partie du pipeline d'outils lors du développement d'une application Web React fait partie intégrante de React Native.

Étape 2 : Il n'y a pas de DOM

Sans surprise, il n'y a pas de DOM sur mobile. Là où nous utilisions auparavant <div /> , nous devons utiliser <View /> et là où nous utilisions <span /> , le composant dont nous avons besoin ici est <Text /> .

 import React from 'react'; import {View, Text, Alert} from 'react-native'; class HelloThere extends React.Component { clickMe() { Alert.alert('hi!'); } render() { return ( <View className="box" onClick={this.clickMe.bind(this)}>Hello {this.props.name}. Please click me.</View> ); } } React.render(<HelloThere name="Component" />, document.getElementById('content'));

Bien qu'il soit assez pratique de mettre du texte directement dans les éléments <div /> , dans le monde natif, le texte ne peut pas être placé directement dans un <View /> . Pour cela, nous devons insérer un composant <Text /> .

 import React from 'react'; import {View, Text, Alert} from 'react-native'; class HelloThere extends React.Component { clickMe() { Alert.alert('hi!'); } render() { return ( <View className="box" onClick={this.clickMe.bind(this)}> <Text>Hello {this.props.name}. Please click me.</Text> </View> ); } } React.render(<HelloThere name="Component" />, document.getElementById('content'));

Étape 3 : Les styles en ligne sont la voie à suivre

React Native nous permet d'utiliser la modélisation Flexbox au lieu de jouer avec le float et inline-block que nous connaissons si bien dans le monde du Web. La chose intéressante est que React Native n'utilise pas de CSS.

 import React from 'react'; import {View, Text, StyleSheet, Alert} from 'react-native'; class HelloThere extends React.Component { clickMe() { Alert.alert('hi!'); } render() { return ( <View style={styles.box} onClick={this.clickMe.bind(this)}> <Text>Hello {this.props.name}. Please click me.</Text> </View> ); } } var styles = StyleSheet.create({ box: { borderColor: 'red', backgroundColor: '#fff', borderWidth: 1, padding: 10, width: 100, height: 100 } }); React.render(<HelloThere name="Component" />, document.getElementById('content'));

L'utilisation de styles en ligne semble déroutante pour les débutants. C'est similaire à la transition que les développeurs de React ont dû traverser lorsqu'ils étaient confrontés à JSX et utilisaient auparavant des moteurs de modèles comme Handlebars ou Jade.

L'idée est que nous n'avons pas de feuilles de style globalement dans la façon dont nous utilisons CSS. Nous déclarons les feuilles de style directement au niveau du composant, et nous avons donc toutes les informations dont nous avons besoin pour voir ce que fait notre composant, la mise en page qu'il crée et les styles qu'il applique.

 import React from 'react'; import {Text} from 'react-native'; var Headline = function(props) { this.render = () => <Text style={headlineStyle.text}>{props.caption}</Text>; }; var headlineStyles = StyleSheet.create({ text: { fontSize: 32, fontWeight: 'bold' } }); module.exports = Headline;

Étape 4 : Gestion des événements

L'équivalent de cliquer dans des pages Web consiste à appuyer sur un élément sur l'appareil mobile. Modifions notre code pour que "l'alerte" s'affiche lorsque nous tapons sur l'élément.

 import React from 'react'; import {View, Text, StyleSheet, TouchableOpacity, Alert} from 'react-native'; class HelloThere extends React.Component { clickMe() { Alert.alert("Hi!") } render() { return ( <TouchableOpacity onPress={this.clickMe()}> <View style={styles.box}> <Text>Hello {this.props.name}. Please click me.</Text> </View> </TouchableOpacity> ); } } var styles = StyleSheet.create({ box: { borderColor: 'red', backgroundColor: '#fff', borderWidth: 1, padding: 10, width: 100, height: 100 } }); React.render(<HelloThere name="Component" />, document.getElementById('content'));

Au lieu que les événements soient directement disponibles sur les composants <View /> , nous devons utiliser explicitement des éléments qui déclenchent des événements, dans notre cas un événement tactile lorsque vous appuyez sur la vue. Il existe différents types de composants tactiles disponibles, chacun d'eux fournissant un retour visuel différent.

Étape 5 : Personnalisez le comportement sur les plates-formes

Il est possible de détecter sur quelle plateforme l'application React Native s'exécute, en accédant à la valeur de Platform.OS . Disons que, dans l'exemple ci-dessus, nous voulions afficher un message d'alerte différent en fonction de la plate-forme sur laquelle nous fonctionnons. Nous pouvons le faire comme ceci :

 ... clickMe() { var message = ''; if(Platform.OS == 'ios') { message = 'Welcome to iOS!'; } else if(Platform.OS == 'android') { message = 'Welcome to Android!'; } Alert.alert(message); } ...

Alternativement, la méthode select est également disponible, qui fournit une syntaxe de type switch :

 … clickMe() { Alert.alert(Platform.select({ ios: 'Welcome to iOS!', android: 'Welcome to Android!' }) ); } ...

Étape 6 : Polices personnalisées et react-native link

Afin d'ajouter une police personnalisée, nous devons franchir quelques étapes. Tout d'abord, assurez-vous que le nom complet de la police et le nom du fichier de la police sont les mêmes : iOS utilisera le nom complet de la police pour récupérer la police, tandis qu'Android utilise le nom du fichier.

Ainsi, si le nom complet de votre police est myCustomFont , assurez-vous que le nom de fichier de la police est myCustomFont.ttf .

Après cela, nous devons créer un dossier assets et pointer npm vers celui-ci. Nous pouvons le faire en créant d'abord le dossier, sous assets/fonts dans le répertoire racine de l'application. N'importe quel autre répertoire fera l'affaire, mais c'est le nom conventionnel utilisé pour le répertoire des polices.

Nous pouvons dire à npm où nous avons nos actifs en ajoutant une propriété Assets sous la section d'intégration npm de React, rnpm :

 "rnpm": { "Assets": [ "./assets/fonts/" ] }

Une fois que nous avons fait tout cela, nous pouvons enfin exécuter react-native link . Cela copiera les polices dans les bons répertoires et ajoutera le xml nécessaire à info.plist sur iOS.

Une fois cela fait, nous pouvons utiliser notre police en la référençant simplement dans n'importe quelle feuille de style par son nom complet. Utilisons-le sur notre élément Text :

 import React from 'react'; import {View, Text, StyleSheet, TouchableOpacity, Alert} from 'react-native'; class HelloThere extends React.Component { clickMe() { Alert.alert("Hi!") } render() { return ( <TouchableOpacity onPress={this.clickMe()}> <View style={styles.box}> <Text style={styles.message}>Hello {this.props.name}. Please click me.</Text> </View> </TouchableOpacity> ); } } var styles = StyleSheet.create({ box: { borderColor: 'red', backgroundColor: '#fff', borderWidth: 1, padding: 10, width: 100, height: 100 }, message: { fontFamily: 'myCustomFont' } }); React.render(<HelloThere name="Component" />, document.getElementById('content'));

Étape 7 : Déplacer les choses

React Native utilise les mêmes règles que Flexbox pour la disposition des composants. Disons que nous voulions positionner notre bouton en bas de l'écran : enveloppons notre TouchableOpacity avec un conteneur View :

 <View style={styles.container}> <TouchableOpacity onPress={this.clickMe.bind(this)}> <View style={styles.box}> <Text style={styles.message}>Hello {this.props.name}. Please click me.</Text> </View> </TouchableOpacity> </View>

Et maintenant, définissons le style de container , ainsi que les autres styles déjà définis :

 container: { flex: 1, justifyContent: 'center', alignItems: 'center' }

Concentrons- alignItems justifyContent Ces deux propriétés contrôlent la manière dont le composant est aligné respectivement le long de son axe principal et de son axe secondaire. Par défaut, l'axe principal est l'axe vertical et l'axe secondaire est l'axe horizontal (vous pouvez modifier cela en définissant la propriété flexDirection sur row ).

justifyContent a six valeurs possibles sur lesquelles il peut être défini :

  • flex-start positionnera tous les éléments ensemble, au début de la boîte englobante du composant.
  • flex-end positionnera tous les éléments à la fin.
  • center positionnera tous les éléments au centre de la boîte englobante.
  • space-around répartira les composants uniformément et centrera les composants dans leurs boîtes englobantes créées.
  • space-evenly répartira également les composants de manière uniforme, mais il essaiera de laisser un espace égal entre les composants et les autres limites.
  • space-between répartira les composants en maintenant l'espacement entre les composants adjacents égal.

alignItems peut être défini sur quatre valeurs possibles : flex-start , flex-end , center et stretch . Les trois premiers se comportent comme ils le font pour justifyContent , tandis que stretch définira le composant pour qu'il occupe tout l'espace disponible le long de l'axe, de sorte que l'axe soit complètement rempli.

Donc, puisque nous voulons que notre TouchableOpacity soit affiché en bas et centré le long de l'axe horizontal, nous pouvons changer le style comme ceci :

 container: { flex: 1, justifyContent: 'flex-end', alignItems: 'center' }

Vous trouverez plus d'informations sur les valeurs justifyContent et alignItems ici et ici.

Étape 8 : Enregistrement de l'application

Lors du développement avec React pour le navigateur, il nous suffit de définir un point de montage, d'appeler React.render et de laisser React faire sa magie. Dans React Native, c'est un peu différent.

 import React from 'react'; import {View, Text, StyleSheet, TouchableOpacity, Alert, Platform} from 'react-native'; class HelloThere extends React.Component { clickMe() { Alert.alert(Platform.select({ ios: 'Welcome to iOS!', android: 'Welcome to Android!' })); } render() { return ( <View style={styles.container}> <TouchableOpacity onPress={this.clickMe.bind(this)}> <View style={styles.box}> <Text style={styles.message}>Hello {this.props.name}. Please click me.</Text> </View> </TouchableOpacity> </View> ); } } var styles = StyleSheet.create({ container: { flex: 1, justifyContent: 'flex-start', alignItems: 'center' }, box: { borderColor: 'red', backgroundColor: '#fff', borderWidth: 1, padding: 10, width: 100, height: 100 }, message: { fontFamily: 'myCustomFont' } }); var MainComponent = function() { this.render = function() { return <HelloThere name="Component" />; } }; AppRegistry.registerComponent('MainComponent', function() { return MainComponent; });

Nous devons enregistrer le composant pour le côté Objective-C des choses, ce qui se fait à l'aide de l'objet AppRegistry . Le nom que nous donnons doit correspondre au nom dans le projet Xcode.

Notre application Hello World React Native a beaucoup plus de lignes de code que son homologue Web, mais d'un autre côté, React Native va un peu plus loin dans la séparation des préoccupations, notamment parce que les styles sont définis avec le composant.

En remarque, nous ne devrions pas relier la méthode clickMe au contexte this dans la méthode render , surtout si notre application React (Native) devient un peu plus complexe. Il relie la méthode à chaque appel de rendu, ce qui peut devenir beaucoup. L'alternative est de lier la méthode à l'intérieur du constructeur.

Exécution de l'application

Pour exécuter l'application, nous devons remplacer le contenu du fichier index.ios.js par le morceau de code de notre application transformée de la dernière étape. Ensuite, nous avons juste besoin d'ouvrir le projet Xcode et d'appuyer sur le gros bouton Exécuter. Tout d'abord, un terminal s'ouvrira avec le serveur React Native, puis la fenêtre du simulateur apparaîtra. Le serveur React Native crée un bundle, que l'application native va ensuite récupérer. Cela permet un cycle de développement rapide de type développement Web, où les modifications seront reflétées presque instantanément dans le simulateur.

Pour Android, il suffit d'ajouter ce qui suit à votre fichier package.json , sous scripts :

 "android-linux": "react-native bundle --platform android --dev false --entry-file index.ios.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/ main/res && react-native run-android"

Et puis exécutez npm run android-linux . Assurez-vous que le répertoire android/app/src/main/assets existe au préalable.

Une fois le terminal apparu, notre application apparaîtra alors dans le simulateur. Appuyez sur CMD + D pour afficher un menu de développement. Cliquer sur la case affichera alors une alerte. La version iOS :

Un téléphone Apple avec une fenêtre contextuelle d'alerte indiquant "Salut".

Et Android rend quelque chose comme ceci :

Un téléphone Android avec une fenêtre contextuelle d'alerte indiquant "Salut".

Pour la distribution, avoir une application qui pointe vers un serveur de développement local ne nous conviendrait pas. Pour cette raison, nous pouvons créer le bundle à utiliser lorsque le serveur React Native ne fonctionne pas avec la commande react-native bundle . Dans ce cas, nous devons mettre à jour la méthode didFinishLaunchingWithOptions de AppDelegate pour utiliser le bundle hors ligne.

Cet exemple d'application est également disponible sur Github.

Travailler avec React Native

Une autre chose à mentionner est que nous utilisons non seulement les concepts React et JavaScript pour nos applications mobiles, mais certains des workflows auxquels les développeurs Web sont habitués sont également disponibles avec React Native. En venant du développement Web, nous sommes habitués aux outils de développement, à l'inspection des éléments et au rechargement en direct.

La façon dont React Native fonctionne est qu'il met tous nos fichiers JavaScript dans un bundle. Ce bundle est soit servi à partir d'un serveur, soit regroupé avec l'application. Le premier est incroyablement utile pour le développement dans le simulateur, car nous pouvons activer le rechargement en direct. Le menu développeur fourni par React n'est en aucun cas aussi puissant que les outils de développement Chrome, mais il offre une expérience de développeur très semblable à celle du Web avec un rechargement et un débogage en direct avec les outils de développement/débogage Chrome (ou Safari).

Les développeurs Web connaissent JSFiddle ou JSBin, un terrain de jeu en ligne pour des tests Web rapides. Il existe un environnement similaire qui nous permet d'essayer React Native dans un navigateur Web.

React Native : un choix solide et moderne

J'avais initialement suggéré une approche plus prudente de React Native. Aujourd'hui, c'est un choix mûr et solide.

L'un des gros avantages de React est qu'il n'impose rien à votre flux de travail, car il ne représente que la couche de vue. Voulez-vous définir votre propre pipeline Grunt ? Ou préférez-vous utiliser Webpack ? Et utiliserez-vous Backbone.js pour vos besoins de modèle ? Ou voulez-vous aller avec des objets JavaScript simples ? Les réponses à toutes ces questions dépendent entièrement de vous, car React n'impose aucune restriction à ces choix. Comme le site officiel l'avait dit : "Puisque React ne fait aucune hypothèse sur le reste de votre pile technologique, il est facile de l'essayer sur une petite fonctionnalité dans un projet existant."

Dans une certaine mesure, cela est également vrai pour React Native. Les développeurs mobiles peuvent intégrer React Native dans le cadre de leur application, tirer parti du flux de travail de développement inspiré du Web et choisir d'intégrer la bibliothèque à plus grande échelle si nécessaire.

En tout cas, une chose est sûre : React Native ne s'en va pas. Facebook a un énorme intérêt à avoir plusieurs applications alimentées par React Native dans les magasins d'applications. La communauté autour de React Native est énorme et continue de croître.

Connexes : Construire un scanner QR : un didacticiel sur l'appareil photo natif React