L'auteur du matériel, dont nous publions la traduction, a récemment publié sa première application mobile écrite en React Native. Il se trouve que cette application était également son premier projet, qu'il a créé en tant que programmeur indépendant. Ici, il parlera de ce à quoi il a dû faire face pendant le travail - de l'initialisation du projet à sa publication sur l'App Store et Google Play.

Pourquoi ai-je choisi le freelance?
En mai dernier, j'ai présenté un merveilleux projet indépendant. À cette époque, j'étais développeur full-stack dans une startup à Stockholm. C'était mon premier travail de programmation, j'y suis arrivé il y a tout juste un an (
ici j'en parle plus en détail).
L'été approchait rapidement, le rythme de travail, avant ce fou, jour après jour, il devenait plus calme. Une fois, il y a eu une semaine où, par ordre de priorité, j'ai dû m'occuper du support technique. J'ai dû faire face à quelques erreurs, je m'ennuyais un peu, le travail ne m'a pas plu.
C'est lorsque j'étais d'humeur si sombre que mon père m'a informé de son intention de créer une application mobile pour les clients de son entreprise. Bien qu'il sache que j'étais très occupé au travail et ne s'attendait pas à ce que je donne tout mon temps pour mettre en œuvre son idée, il a quand même demandé si je voulais devenir une sorte de consultant dans ce nouveau projet. J'ai alors senti que j'avais faim d'un travail mental intéressant et j'ai donc répondu positivement à sa question. Même si je n'avais pas prévu cela au départ, du consultant, je suis devenu un développeur d'applications de premier plan.
Ici, vous vous demandez peut-être pourquoi quelqu'un pourrait même essayer de faire du développement mobile après ne pas avoir travaillé comme développeur Web professionnel pendant un an? Ne serait-il pas plus sage de continuer à acquérir de l'expérience dans un créneau choisi, de grandir professionnellement et de créer un CV impressionnant?
Je suis tout à fait d'accord que ce serait beaucoup plus raisonnable. Mais je suis un "travailleur multipostes" sans espoir qui a décidé il y a plusieurs années de prendre des décisions de carrière basées non pas sur une certaine stratégie, mais sur mes propres préférences. J'ai décidé de faire ce qui m'apporte de la joie. En d'autres termes, mon CV semble maintenant tel qu'il peut difficilement être amené dans un état encore plus erratique.
Bien sûr, faire ce que vous aimez et suivre une stratégie de carrière ne sont pas nécessairement des phénomènes mutuellement exclusifs. En fait, j'ai beaucoup aimé mon travail précédent et l'employeur. Il se trouve que je suis tombé sur un autre projet, dont l'envie s'est avérée plus forte que le désir de faire ce que je faisais auparavant.
Qu'est-ce qui a rendu ce projet si attrayant pour moi? Qu'est-ce qui l'a rendu plus intéressant que de travailler sur un produit en développement rapide utilisé par des milliers d'entreprises, au sein d'une équipe composée des meilleures personnes que j'ai rencontrées? On peut répondre à cette question de cette façon: c'est la liberté, c'est le défi qui m'a donné le besoin de résoudre un problème difficile, et c'est le désir de s'épanouir.
Pourquoi a-t-il été décidé d'utiliser React Native?
Au moment où j'ai rejoint le projet, mon client avait déjà reçu plusieurs offres d'agences numériques locales. Avant même d'envisager la possibilité de développer l'application de manière indépendante, on m'a demandé de manière amicale d'évaluer ces propositions. Quand je les ai regardés, j'ai été simplement étonné de leur faible qualité.
L’une des agences a envoyé un aperçu de la conception de l’application qui, en plus d’être désordonnée, ne correspondait pas non plus à l’identité de l’entreprise reflétée sur le site du client. Un autre a suggéré des prix exorbitants - à la fois pour le développement et pour le soutien de projet. Le troisième, semble-t-il, a envoyé la proposition, sans même avoir vraiment étudié les exigences du client. Toutes les agences qui ont soumis les propositions avaient un point commun: elles allaient créer une application en utilisant le cadre hybride Cordova.
Mais ce n'est pas tout. Bien que Cordova soit un outil entièrement gratuit et open source, l'une des agences a même tenté de cacher des informations sur la technologie spécifique qu'elle utilise. Au lieu de cela, les représentants des agences ont parlé d'une plate-forme de développement d'applications mobiles «interne» créée en interne. Il semble que nous parlions d'un petit add-on sur Cordova, conçu uniquement pour garantir fermement les droits exclusifs de cette agence pour le service de l'application et rendre la transition future possible du client vers un autre développeur difficile et coûteuse. D'une manière générale, les propositions en question n'étaient pas particulièrement impressionnantes.
Il convient de noter que je n'ai rien contre les cadres hybrides. J'utilise constamment des applications basées sur eux. Cela, par exemple, Gmail, Slack, Atom, Figma. Cependant, j'avais entendu parler de React Native pendant un certain temps, de la façon dont cette bibliothèque vous permet de créer des applications mobiles multiplateformes en utilisant JavaScript qui n'étaient pas hybrides!
Et maintenant quoi? Est-il nécessaire, d'une manière délicate, de prendre en charge iOS et Android lors du développement d'applications JavaScript natives? Cette question s'est posée du fait que lorsque j'étais intéressé par de telles applications, il s'est avéré que les applications iOS étaient écrites en utilisant Objective-C ou Swift, et Java ou Kotlin étaient utilisées pour développer des applications Android.
Bien sûr, il n'y a pas de trucs spéciaux ici. J'avais donc encore une question. Comment les applications React Native peuvent-elles être appelées de véritables applications natives? Si vous répondez à cette question en un mot, il s'avère que le tout est dans l'API. Il m'a fallu plus de temps pour comprendre cela que je ne voudrais le reconnaître, mais la façon dont les applications React Native, dites natives, fonctionnent avec des plates-formes mobiles, ne consiste pas à lancer du code JavaScript ou à compiler ce code dans code natif. Le fait est que ces applications exécutent des requêtes API qui affichent des composants natifs à l'aide d'Objective-C sur iPhone et Java sur Android.
Si vous voulez avoir une compréhension plus approfondie des bases de React Native - je recommande
cette réponse à Quora,
ceci est une présentation avec React Conf, et
ce matériel, qui raconte la sortie de React Native.
Bien qu'à cette époque, je ne savais pas exactement ce qui se passait dans les entrailles des applications natives de React, je savais que le travail de ces applications était réduit à l'exécution de code natif. C'était mon principal argument contre le choix d'une des solutions basées sur Cordoue proposées par les agences. Je pensais que si une entreprise avait besoin d'une application mobile, cette application devrait être native. Si quelqu'un a besoin d'une application basée sur HTML / CSS / JS, il serait préférable de dépenser de l'argent simplement pour améliorer les capacités mobiles de son application Web.
Lorsque j'ai partagé ce raisonnement avec un client, il m'a demandé si je connaissais quelqu'un qui pouvait créer une telle application. J'ai répondu que je ne savais pas. Ensuite, ils m'ont demandé si je pouvais le faire moi-même. "Je ne peux pas," répondis-je. Cependant, à ce moment-là, j'étais déjà intéressé par tout cela et je ne pouvais tout simplement pas m'empêcher d'expérimenter avec React Native, en prenant les spécifications de l'application comme base de mes expériences.
Avant de m'en rendre compte moi-même, j'ai pu créer la base de l'application. Par conséquent, quelques semaines seulement après cette conversation, le client et moi avons convenu de développer l'application pour lui.
Spécifications d'application
Avant de nous plonger dans les détails techniques, je voudrais parler un peu du type d'application avec laquelle nous avons affaire.
Le client pour lequel l'application est développée est une entreprise de Stockholm, qui s'occupe de la gestion du coworking, des bureaux collectifs. En d'autres termes, nous parlons d'espaces de bureaux qui peuvent être loués par différentes entreprises. À l'heure actuelle, mon client possède environ 10 de ces bureaux existants dans lesquels environ 400 entreprises de 1 400 employés louent des locaux. Ce sont les locataires des bureaux et le public cible de l'application.
Zone de loisirs dans l'un des coworkingAprès avoir discuté de la future application avec le chef de projet, j'ai réussi à découvrir certaines exigences pour le projet:
- La possibilité de se connecter, de se déconnecter et de réinitialiser le mot de passe. Veuillez noter que tous les comptes d'utilisateurs sont créés par des administrateurs et que l'application ne prend pas en charge l'enregistrement dans le système. Par conséquent, si vous décidez de télécharger cette application, vous ne pourrez pas travailler avec.
- Affichez et modifiez le profil utilisateur: nom, adresse e-mail, mot de passe, avatar.
- Prise en charge des notifications push.
- La rubrique Accueil, avec laquelle l'utilisateur peut prendre connaissance des actualités de l'entreprise dans son ensemble, et notamment des actualités concernant le coworking loué par l'entreprise.
- Section communautaire, avec laquelle l'utilisateur peut afficher des informations sur divers coworking, contacter leurs responsables et voir quelles entreprises sont engagées dans un certain coworking.
- Section de conférence, avec laquelle vous pouvez réserver des salles de réunion et gérer les réservations.
- Sélection de section, dans laquelle l'utilisateur peut trouver des remises et des offres exclusives.
- Vous devez d'abord créer une version iOS, puis ajouter le support Android.
- Application Web pour l'administrateur, qui vous permet de gérer les informations affichées dans l'application React Native. Bien que je parlerai ici principalement du développement frontal, je pense qu'il serait approprié de mentionner que la partie serveur de l'application pour l'administrateur est basée sur Ruby on Rails, Postgres et Heroku.
Vous remarquerez peut-être que ce projet a des exigences plutôt modestes. Peut-être que quelque chose dans cet esprit peut être appelé un bon exemple de la première application que quelqu'un va développer en utilisant un nouvel ensemble de technologies. Si vous êtes intéressé à jeter un coup d'œil à ce que j'ai fini par (et, en passant, à décider de passer du temps à lire l'histoire sur la façon dont tout cela a fonctionné pour moi), voici un aperçu de la première version de l'application.
Première version de l'applicationToujours en train de lire? Super, alors passons.
Apprendre des meilleurs
Imaginez que vous avez promis à vos amis de leur construire une maison. Mais vous ne savez pas comment faire. Vous ne savez vraiment pas par où commencer. Que faut-il faire en premier dans une telle situation? La réponse est évidente: trouver quelqu'un qui peut construire des maisons et apprendre de lui.
À strictement parler, c'est exactement ce que j'ai essayé de faire. Et j'ai eu beaucoup de chance de trouver exactement ce dont vous avez besoin. Donc, après seulement quelques heures de recherche de matériel de formation React Native, j'ai trouvé sur YouTube un
cours vidéo Harvard React Native en 13 parties. Chaque conférence, d'une durée de 90 à 120 minutes, était consacrée à un sujet distinct. En conséquence, j'ai été confronté à environ 23 heures de matériel de formation de haute qualité.
Ayant trouvé ce cours, je me mis immédiatement, comme un obsédé, à étudier. En conséquence, après plusieurs semaines de cours sur lesquels je pouvais passer des soirées et des week-ends, j'ai terminé ce cours et créé une bonne base pour l'application.
Maintenant, je peux dire que ce cours, sans aucun doute, est le meilleur que j'ai réussi à trouver. Les cours concis et bien préparés ont bien sûr joué un rôle positif énorme à l'école, mais je ne peux que noter les compétences de l'enseignant. Je décrirais le style de conduite de ces cours avec les mots suivants: vitesse, extrême praticité, concentration. Pas d'eau, pas de blagues ou d'histoires hors de propos. Contrairement à ce que votre humble serviteur écrit ici ...
D'une manière ou d'une autre, il y avait le sentiment que tant d'informations utiles étaient contenues dans chaque conférence qu'il faudrait deux fois plus de temps pour les présenter à de nombreux autres enseignants. En d'autres termes, ce cours est très similaire au célèbre Harvard CS50.
Par conséquent, si vous souhaitez trouver un point d'ancrage pour votre première application React Native, je recommande définitivement ce cours pour vous. Bien qu'ici, il convient de noter une caractéristique. Ce cours utilise la boîte à outils
Expo . Il s'agit d'un excellent outil adapté à la plupart des applications simples, qui prend toutes sortes de subtilités concernant le travail avec les plates-formes mobiles. Mais si vous, comme moi, souhaitez créer la base d'un projet qui, tôt ou tard, peut se transformer en une application assez grande et complexe, et que vous souhaitez en même temps une totale liberté d'action, vous feriez probablement mieux d'initialiser le projet en React Native.
La deuxième «ressource de formation» que j'ai pu utiliser était mes collègues. Heureusement, l'entreprise où j'ai travaillé a également commencé à développer le projet React Native. Bien que je ne sois pas moi-même impliqué dans ce projet, j'ai beaucoup appris, juste parler à ceux qui ont travaillé sur ce projet et analyser leur code.
Maintenant que nous avons discuté de tout ce qui va avec le développement d'applications React Native, il est temps de passer aux problèmes techniques.
Environnement de développement
Après avoir utilisé une équipe de la forme
react-native init MyApp
, j'ai créé la base de l'application, l'une des premières tâches à laquelle j'ai été confrontée a été le développement d'un nouvel environnement de développement.
Si vous êtes arrivé à l'environnement React Native à partir du développement Web habituel, il convient de noter que beaucoup de choses vous sembleront familières. Pour moi, cela signifiait que je continuais à utiliser Atom comme éditeur de code, iTerm comme terminal et GitUp comme interface pour travailler avec git. (Si les fans de Vim lisent ceci en ce moment, je suggère que tout le monde ne soit pas convaincu.) Mais, en plus des outils ci-dessus, j'avais besoin d'autre chose pour développer des applications React Native.
Par exemple, je devais m'habituer à l'émulateur iOS. Bien que l'exécution, par les outils de ligne de commande, de la commande
react-native run-ios
, semble d'une simplicité trompeuse, au tout début d'un simple appel à cette commande n'était pas suffisant pour que l'émulateur fonctionne correctement. Étant donné que de nouveaux packages npm ont été ajoutés au projet presque tous les jours (et plus tard, un certain nombre de modules CocoaPod natifs), j'ai, beaucoup plus près que je le souhaitais, été obligé de me familiariser avec le rituel désagréable d'effacement des ressources Watchman et du cache Haste, en supprimant le dossier node_modules, réinstallation des modules et réinitialisation du cache Metro Bundler. Heureusement, toutes ces tâches peuvent être résolues à l'aide de la commande suivante:
watchman watch-del-all && rm -rf tmp/haste-map-react-native-packager && rm -rf node_modules && yarn && npm start --reset-cache
Dans 9 cas sur 10, une telle "danse avec un tambourin" a permis à l'émulateur de reprendre vie. Parfois, cependant, même cela ne suffisait pas. Ensuite, j'ai dû me plonger dans la description des messages d'erreur sur GitHub et lire les discussions sur StackOverflow.
La racine de certains autres problèmes était le fait que pendant longtemps j'ai pensé que pour résoudre certains problèmes, il était nécessaire d'exécuter Xcode. Et croyez-moi, vous vous efforcerez de rester dans cette maison d'horreur IDE le moins de temps possible.
Une histoire similaire a été avec le lancement de l'émulateur avec une certaine version de l'iPhone. Si quelqu'un m'avait dit plus tôt que la commande ci-dessous résout ce problème directement à partir de la ligne de commande, alors j'aurais peut-être vécu un peu plus facilement dans mes premiers mois de développement de React.
react-native run-ios --simulator='iPhone X'
D'autres exemples des difficultés à s'habituer au nouvel environnement de développement comprennent le
processus en trois étapes de préparation de la version finale de l'application (pour le placement sur l'App Store ou dans un environnement d'intégration continue, comme Visual Studio App Center ou Firebase) et le processus de transition de la version finale à la version, destiné au débogage (en mode développement). Beaucoup trouveront peut-être évident que les modifications nécessaires au projet peuvent être apportées à l'aide de n'importe quel éditeur de texte. En tout cas, ce n'est qu'un exemple de quelques petites choses qui ont eu un impact inattendu sur mon flux de travail lorsque je travaillais en mode développement.
Et enfin, il a fallu un certain temps pour s'habituer à la nécessité de basculer constamment entre les différentes applications macOS nécessaires pour résoudre les tâches que je, lors du développement d'applications Web, généralement résolues en utilisant Chrome seul.
Afin de regarder ce que le code JavaScript écrit sur la console et d'analyser, à des fins de débogage, la sortie HTML / CSS, je me suis tourné vers le
débogueur natif React . Afin de suivre l'état de la demande, les actions soumises, les demandes d'API et les réponses reçues, j'ai utilisé
Reactotron . Bien que j'ai trouvé ces deux applications extrêmement utiles, je n'ai pas pu m'empêcher de penser à mon flux de travail habituel utilisé pour créer des applications Ember.js, quand je pouvais résoudre toutes ces tâches dans le même environnement dans lequel mes applications étaient exécutées (en utilisant le plugin Inspecteur Ember pour Chrome).
La navigation
L'organisation de la navigation / du routage semble être une tâche très difficile pour React Native. Au cours de l'existence de ce cadre, de nombreuses solutions différentes à ce problème sont apparues, mais il existe encore quelque chose que l'on pourrait appeler une norme universellement reconnue. J'ai décidé d'utiliser la bibliothèque React-Navigation, mon choix a été principalement influencé par le fait qu'ils ont parlé de cette bibliothèque dans le cours React Native que j'ai suivi, ainsi que par le fait que mes collègues l'aient utilisée.
Si j'ai investi un peu de temps dans une étude suffisamment approfondie de cette question, je pourrais découvrir ce qui suit:
- Le projet React-Navigation compte environ 15 000 étoiles sur GitHub et 86 problèmes non résolus. Il est entièrement basé sur JavaScript et propose la documentation la plus détaillée parmi les solutions de navigation que j'ai vues.
- La bibliothèque de navigation native de réaction a marqué environ 10 000 étoiles, il s'est avéré avoir 162 problèmes non résolus. Cependant, il utilise non seulement JavaScript. Pour travailler avec, vous devez modifier des fichiers natifs.
- Le référentiel react-router possède environ 35 000 étoiles et une liste de 55 problèmes en suspens sur GitHub. Certes, ces indicateurs ne peuvent pas être directement comparés aux autres projets décrits ici, car ce référentiel comprend des packages conçus non seulement pour React Native, mais aussi pour React.
- Le projet de navigation native compte environ 3 000 étoiles et 55 problèmes non résolus. Ceux qui vont l'étudier et l'utiliser devraient tenir compte du fait qu'il est toujours en version bêta, qu'il utilise non seulement JavaScript, et qu'Airbnb est engagé dans son support (cette société a décidé d'abandonner React Native )
Mais, même compte tenu de ce qui précède, j'aurais probablement choisi React-Navigation de toute façon, car je n'avais pas le temps d'essayer toutes ces bibliothèques, comme, par exemple, l'auteur de
ce rapport. Enfin, comme cela a été dit dans ce rapport, le choix d'un outil d'organisation de la navigation est une question dont la solution ne dépend pas de laquelle de ces outils peut être qualifiée de meilleure, mais de laquelle est la mieux adaptée aux besoins d'un projet particulier.
Après avoir travaillé avec react-navigation pendant environ 9 mois, je dois dire que je n'ai vraiment rien à redire. Si vous comparez cette bibliothèque avec la bibliothèque
router.js familière utilisée dans
Ember.js , je peux dire que c'est quelque chose de complètement nouveau.
Il m'a été très facile de gérer les trois principaux types d'outils de navigation React-Navigation. Ce sont
StackNavigator
,
TabNavigator
et
DrawerNavigator
. Il était beaucoup plus difficile de comprendre comment combiner ces outils afin de créer le système de navigation d'application dont j'avais besoin.
Par exemple, le fait que le composant
DrawerNavigator
devrait être l'élément racine du système de navigation (une étape au-dessus du composant principal
TabNavigation
) n'était absolument pas évident pour moi. Si c'est difficile à imaginer,
DrawerNavigator
quoi ressemble
DrawerNavigator
en action (dans une application réelle, tout fonctionne beaucoup plus facilement).
DrawerNavigator de react-navigation en actionComme vous pouvez le voir, je devais ouvrir la barre de navigation latérale d'un coup, en étant sur n'importe quel écran d'application.
J'ai perçu la barre latérale comme quelque chose de secondaire par rapport à la barre de navigation principale située en bas de l'application. Par conséquent, il m'a semblé que
DrawerNavigator devait être placé dans l'arborescence de l'itinéraire (il est illustré ci-dessous) soit sous le
BottomTabNavigator principal, soit au même niveau que cet élément.
Cependant, après avoir beaucoup souffert, essayant de forcer la barre latérale à l'endroit où cela s'est révélé inapproprié, j'ai réalisé que, conformément aux caractéristiques de
DrawerNavigator
-Navigation,
DrawerNavigator
devrait être placé un cran au-dessus du
BottomTabNavigator
, c'est-à-dire dans racine de l'arborescence de navigation. J'espère que ma découverte aidera l'un des lecteurs de ce matériel à gagner du temps qui serait autrement consacré à la lecture de la documentation et des documents sur GitHub.
Voici à quoi ressemble l'arborescence de navigation de l'application. Ici, en tant qu'élément racine,
MainDraverNavigation
utilisé.
L'arborescence de navigation finale de la première version de l'applicationIci, vous vous demandez peut-être pourquoi, pour les sections Communauté et Conférence, vous avez besoin de
StackNavigator
et
TabNavigator
. Ne pouvez-vous pas simplement déposer la couche
StackNavigator
et aller directement à
TabNavigator
?
Le fait est que j'avais besoin de chacun des deux éléments
TabNavigator
pour avoir un titre. Les voici.
TabNavigator, titreIci encore, mes suppositions ne correspondaient pas à l'appareil de navigation React. Je pensais que
MaterialTopTabNavigator devrait être un composant de navigation tout à fait normal, j'ai donc décidé qu'il devrait y avoir une option intégrée dans ses paramètres qui vous permet de définir un titre. Il s'est avéré que rien de tel n'était là, et c'est pourquoi j'ai dû utiliser
StackNavigator
comme couche intermédiaire, ajoutant, par conséquent, un niveau de complexité supplémentaire à l'infrastructure d'application et guidé par des considérations assez «cosmétiques».
Ce manque de réaction-navigation, en plus, m'a causé beaucoup plus de problèmes. Ils ont notamment consisté à organiser le pliage et la disparition de l’image d’en-tête lors du défilement de l’utilisateur dans la liste des éléments organisés par
FlatList . Étant donné que les titres des sections Accueil et Sélection étaient affichés dans le même
StackNavigator
que les listes de leurs éléments, ce problème ne serait pas difficile à résoudre en laissant simplement le titre défiler avec le reste de la liste.
Mais dans le cas des sections Communauté et Conférence, je n'ai pas trouvé de moyen d'appliquer la même solution, car les en-têtes sont affichés à l'aide des éléments
StackNavigator
et les listes sont affichées à l'aide des éléments
StackNavigator
, un cran plus haut dans l'arborescence de navigation. En conséquence, j'ai refusé de faire défiler le titre, ce qui a introduit une hétérogénéité désagréable dans l'application.
Défilement dans TabNavigator et StackNavigatorBien que le problème décrit avec le titre dans l'émulateur simulant Iphone X ne semble pas sérieux, sur le petit écran, le titre peut occuper environ 20% de l'espace d'écran disponible. Si quelqu'un sait comment résoudre ce problème, faites-le moi savoir.
Le même problème avec
TabNavigator
a également été ressenti dans la section Destination. Comme le montre la figure suivante, à droite, je voulais placer un autre élément
TabNavigator
sur l'onglet
TabNavigator
Spaces afin d'afficher les trois premiers onglets Info, Members et Contact.
Lorsque vous travaillez avec
TabNavigator
il était difficile de placer un diaporama en haut de l'élément sans avoir à compliquer la décision et à ne pas causer beaucoup de problèmes de navigation (principalement liés aux options de navigation). J'ai donc dû recourir à un package JS appelé
react-native-swiper afin de travailler avec ces trois onglets. Il est à noter que cette solution me conviendrait parfaitement si son application ne conduisait pas à une animation abrupte de lignes mettant en valeur les en-têtes de tabulation. Dans tous les cas, j'ai considéré cet inconvénient comme un paiement équitable pour la possibilité d'éviter les problèmes avec un système de navigation alternatif.
Comparez TabNavigator de react-navigation avec react-native-swiper (notez la différence dans l'animation des lignes dorées sous les noms des onglets)Voici les conclusions que j'ai tirées après la mise en œuvre du sous-système de navigation d'application:
- Il existe de nombreuses solutions bien documentées pour organiser la navigation dans les applications React Native, parmi lesquelles j'ai choisi react-navigation. Cela correspond le mieux à mes besoins.
- La bibliothèque react-navigation simplifie considérablement le démarrage d'un projet si le développeur ne sait pas grand-chose sur le fonctionnement des systèmes de navigation des plates-formes mobiles.
- La bibliothèque React-Navigation possède des fonctionnalités qui ne sont pas intuitives (du moins pour un développeur Web), mais il n'y a rien qui ne puisse être contourné, mais pas de la manière la plus efficace.
Écran d'accueil
En lançant une nouvelle application dans l'émulateur créé à l'aide de la commande
react-native init
, en la rechargeant constamment au fur et à mesure que vous y apportez des modifications, vous vous rendez très vite compte que l'application a besoin d'un joli écran de démarrage (on les appelle aussi «écrans de démarrage»).
Comment faire un écran de démarrage est bien écrit
ici , donc je ne répéterai pas les mots de l'auteur de ce matériel. Je ne parlerai que du problème que j'ai rencontré, et sur lequel il n'y a rien dans ce guide. Voici à quoi ressemble ce problème:
L'écran de démarrage avec un problèmeCe problème apparaît dans de rares cas sur iOS, mais certains utilisateurs de l'application le rencontreront probablement. J'ai découvert ce problème pour la première fois lorsque je travaillais à un endroit, où je ne pouvais pas utiliser le WiFi et que je connectais mon ordinateur portable à Internet 4G via un téléphone. Les utilisateurs d'iPhone savent que lorsque le téléphone distribue Internet, sa barre d'état devient bleue et augmente. Cela a "cassé" l'image sur mon écran de démarrage lorsque j'ai lancé l'application sur le téléphone. Le même problème s'est posé lors de l'appel.
En conséquence, après avoir fouillé pendant un certain temps dans le référentiel d'
écran de réaction natif et n'y trouvant rien d'utile, j'ai décidé de contourner ce problème en masquant complètement la barre d'état tout en affichant l'écran de démarrage.
C'est très simple - ajoutez simplement la clé
UIStatusBarHidden
, en lui affectant la valeur logique, puis, après avoir appelé
SplashScreen.hide()
, définissez la propriété
hidden
du composant React Native
StatusBar
sur
StatusBar
.
Gestion de l'État
J'ai le sentiment que depuis deux ans j'entends chaque jour parler de la priorité de l'accord sur la configuration, le principe de la Convention sur la Configuration (CoC). C'était donc à mon travail précédent. Et ce n'est pas surprenant, car là, sur le serveur, nous avons utilisé Ruby on Rails, et sur le client - Ember.js - deux frameworks, dont l'essence correspond au mieux au principe CoC. Je pensais savoir ce que cela signifiait, mais le processus d'exploration de la gestion des états dans React Native m'a donné une toute nouvelle compréhension de ce principe.
Bien que j'aie, dans plusieurs applications très simples, expérimenté la bibliothèque React influencée par ce principe, je n'ai jamais créé quelque chose d'assez grand basé sur cela qui me permettrait d'apprécier les avantages de l'utilisation de conteneurs d'état comme
Redux ou
MobX . La plupart de mon expérience dans la gestion de l'état des applications JS concerne
Ember Data (il s'agit du système intégré Ember pour gérer l'état et organiser le stockage de données persistantes).
Étant donné que la bibliothèque Redux me semblait être l'une des meilleures solutions au problème de gestion de l'État dont j'avais entendu parler pendant de nombreuses années (et qui a été discuté dans le cours React Native que j'ai couvert), en général, je n'ai pas regardé vers ses concurrents . Je voulais juste équiper mon application du meilleur des systèmes de gestion d'état existants et le faire sans trop d'effort.
Dans Ember, 90% de l'infrastructure de données est entre les mains du programmeur prêt à l'emploi. Je ne soupçonnais pas que dans mon projet actuel, tout serait exactement le contraire. En fait, non seulement React, mais Redux, la bibliothèque de gestion d’état la plus populaire, ne donne rien d’utile pour maintenir l’état global. Cette bibliothèque est si légère que le programmeur doit assumer 90% des soucis de travailler avec des données à l'intérieur de l'application afin de créer un système de gestion d'état décent.
Après avoir découvert un développeur beaucoup moins expérimenté que maintenant, la chose la plus difficile pour moi a été de m'habituer aux nouvelles fonctionnalités et aux principes de l'immunité. Après avoir supporté le volume de travail étonnamment important qui doit être fait pour télécharger simplement les données du serveur ou les envoyer au serveur, tout cela s'est réuni sous la forme de 7 étapes assez simples:
- Ajoutez trois constantes au fichier avec des constantes:
SOME_ACTION_REQUEST
, SOME_ACTION_FAILED
, SOME_ACTION_SUCCEEDED
. - Ajoutez le créateur d'action au fichier d'action.
- Traitez trois actions dans un réducteur approprié et, si nécessaire, ajoutez un nouveau réducteur au système et incluez-le dans le réducteur racine.
- Ajoutez des travailleurs à une saga appropriée et, si nécessaire, ajoutez une nouvelle saga au système et incluez-la dans la saga racine (j'utilise la bibliothèque redux-saga pour traiter les actions asynchrones).
- Ajoutez une fonction pour gérer toutes les demandes d'API possibles.
- Mappez les données nécessaires de l'état aux propriétés dans le composant React correspondant.
- Soumettez l'action
SOME_ACTION_REQUEST
partir du composant React correspondant.
Redux et redux-saga, bien sûr, ont des fonctionnalités beaucoup plus étendues, mais compte tenu de ce qui m'intéresse actuellement, les 7 étapes ci-dessus sont ce que Redux est pour moi.
Séances
Nous avons donc mis en place l'environnement de développement pour les applications natives React, créé une arborescence de navigation, préparé l'infrastructure de gestion des états. Que sera-t-il bon de faire dans la prochaine étape du projet? Pour moi, la création d'un système d'authentification des utilisateurs était une réponse tout à fait naturelle à cette question. Alors maintenant, nous allons parler des sessions.
Si vous êtes venu dans la sphère React Native à partir du développement Web, vous allez gérer les sessions sans trop de difficulté. Si vous êtes même un peu familier avec les concepts sur lesquels le stockage
LocalStorage est
basé , alors il vous suffit de savoir que lorsque vous travaillez avec React Native, l'accès à ce stockage doit être remplacé par un appel à
AsyncStorage . Il s'agit du niveau d'abstraction qui vous permet de stocker des données au format clé-valeur entre les sessions. En d'autres termes, vous pouvez ici stocker le jeton d'authentification généré sur le serveur, transmis au client après que l'utilisateur s'est correctement connecté au système.
Listes
Si nous parlons de travailler avec des listes, j'ai le sentiment que dans React Native, ce problème a été assez bien résolu. En général, on peut noter que le développeur a trois possibilités. Si cela fonctionne avec des listes statiques, les données présentées dans lesquelles ne change pas, alors
ScrollView en aura probablement assez.
Si vous devez travailler avec des listes plus longues, qui sont d'ailleurs dynamiques, alors il vaut la peine de regarder FlatList . Si nous parlons de listes encore plus grandes, qui, en outre, peuvent être divisées en sections, il sera utile de recourir aux capacités de SectionList .Pour les listes dynamiques, j'utilise exclusivement FlatList
. Et bien que moi, à un niveau intuitif, comme ces listes et la possibilité de les configurer, j'ai, en travaillant avec elles, rencontré plusieurs problèmes. Je vais maintenant en parler.▍Dessiner la liste pour mettre à jour son contenu
FlatList
,
refreshControl
. , , , , . , React Native , . —
RefreshControl . , .
RefreshControl, , ,
refreshControl
,
RefreshControl
, , . , , :
- , , . ,
handleRefresh()
. - , , « » ( ).
— .
, , , , . , , ,
GitHub.
,
refreshControl
onEndReached
( )
fetching
. , - ,
false
true
, — , , 250 ,
RefreshControl
, .
,
setTimeout()
fetching
350 . . , ,
setTimeout
— , ,
handleRefresh()
handleLoadMore()
—
refreshing
loadingMore
. , , , , - .
,
onRefresh
refreshing
refreshControl
. ,
refreshControl
, , , , .
▍
, . — , , Load More , , , , .
FlatList. , , 2, onEndReached , 2-,
onEndReached
. .
onEndReachedThreshold
,
FlatList
, ,
onEndReached
. .
100 , , 10 , 1,
onEndReachedThreshold
, ,
onEndReached
, , 90-. 2, , 2- , — 80- , .
, , , ,
FlatList
. , , , ,
handleLoadMore()
,
onEndReached
, , — 10 .
, ,
loadingMore
, ,
handleLoadMore()
, , ,
!loadingMore
. , , .
▍
ListLoadingComponent
FlatList
, ,
ListHeaderComponent
,
ListEmptyComponent
ListFooterComponent
, , - , , , .
,
render()
.
▍
, , , . , , .
,
scrollToOffset
FlatList
, , . , .
ref
FlatList
:
<FlatList ref={(ref) => { this.newsListRef = ref; }} ... />
, .
ScrollToOffset
handleScrollToTop()
, , , react-navigation, , :
componentDidMount() { this.props.navigation.setParams({ scrollToTop: this.handleScrollToTop, }); } handleScrollToTop = () => { this.newsListRef.ScrollToOffset({ x: 0, y: 0, animated: true, }); };
, react-navigation 3
ref
,
BottomTabNavigator
.
, , . , , 4G- ( , , 3G), , , , , .
, , , , , , , . . , , , , .
, , . 7 ,
image
, , ( , ).
▍
, , .
react-native-image-picker , Cloudinary Carrierwawe Rails-.
, Node-API Cloudinary
react-native-fetch-blob . , , , , , .
, , react-native-fetch-blob, . , react-native-fetch-blob ,
API JS FormData . , react-native-fetch-blob
rn-fetch-blob , .
▍
, React Native
Image style
,
source
resizeMode
. , , - , , , .
, , , . , , , . .
Avatar react-native-elements.
,
Image
. , - , .
, , . .
react-native-slideshowreact-native-slideshow , , . , , , , , , .
▍
7 , , . , — , , . , - . .
, , -, , , , - ( — ), , , , Facebook . , .
, , React Native-. , . —
react-native-loading-placeholder , , , . —
react-native-linear-gradient , . , , , , , , , , .
react-native-loading-placeholder react-native-linear-gradient▍
— . , React Native
Image
. , -
CachedImage
react-native-cached-image .
npm-
Image
, , ,
CachedImage
. Reactotron , , .
, , , . , , Cloudinary, 95% , , 4%. .
, .
CachedImage
activityIndicatorProps={{ animating: false }}
, .
▍
React Native -
Picker . - , ( - ), JS-, . ,
react-native-picker-select ,
<select>
iOS Android .
JS-, React Native- (
lodash , ), , , , . , , - . , .
▍
react-native-calendars Wix. :
- iOS , . , , , -, — .
- React Native —
DatePickerIOS
DatePickerAndroid
, , . - , , , Apple Google.
, . , , — .
react-native-calendars react-native-picker-select▍
— , .
SaaS-, . SOAP, API Conference. , , , , .
, , , 5 . - , JavaScript
Date UTC, , . , , , , , - . « », — .
, ,
moment-js , React Native,
timezone , :
const timeSthlmAfterFive = moment().isAfter(moment.tz('17:00:00', 'HH:mm:ss', 'Europe/Stockholm'), 'second');
, , , . React Native -, , , , , ,
font-face
CSS.
. , .
, 10 -.
react-native-vector-icons .
, ,
CI/CD, DevOps- -, .
( ) , - . , . GitHub- . , :
. , , , , , , push-. , , , , .
Visual Studio App Center (VSAC).
Chain React 2017 . , , , DevOps-, . , , , , push-,
Codepush . -. , , , , iOS, Android. , - , , , , , - .
Visual Studio App Center ( )« », — , . , (API — ). , , , , -, (, , ).
? Microsoft, , VSAC « ». , , Codepush ( React Native-) HockeyApp ( ), - . , «developers, developers, developers, developers» .
, VSAC , -
Fastlane ,
BuddyBuild Firebase ? , , , VSAC , , , . , , ? , VSAC, , .
VSAC. , , , .
, , , VSAC Apple Developers (Apple, , , ). , , , .
, VSAC, , ,
CI/CD- .
Android
, iOS- , Android . Android Studio Android React Native
Platform . ,
Platform.select()
. - , , ,
Platform.OS
.
, , Google Play , App Store. Pourquoi? , App Store Apple.
Apple
, -, React Native, . , Apple. , , , , , .
Apple, — « ». -, , iOS-, , , , .
— Apple. , , , . Dun & Bradstreet, Apple, . , , , Apple (, , Apple , — ).
, Apple , , — , -. . , — ?
, .
, , Apple Developer . .
. . provisioning-, iOS-, , Apple .p12 push-, dSym-. , , , .
Apple, 50% 24 , 90% — 48 . , , — , , Apple-.
, . «Metadata Rejected». , - . , 5 (
App Store Review Guidelines ), .
, , , — . , , , , , . , — , () .
iOS, . , , , . , , . . , , .
Résumé
, React Native- . React Native-. -. , : . .
, , , , . , , — , .
, - , . . , , , 8 . . .
, . , , - .
, , , 6-7 , . , , , :
- , (iOS Android), , , .
- JavaScript. , , Ember.js.
- React.js, , React-, . , JS-/.
- , Redux.
- DevOps .
- , .
- UI/UX.
- , , , , , , , , .
JS- ,
Flutter ,
NativeScript , Objective-C, Swift, Java Kotlin, React Native .
, -, , React Native , , , . , React Native — , . React Native .
Chers lecteurs! ?