Créer un menu natif crossplatform avec React Native

Ou comment gérer les composants natifs par plateforme ?

Le blog Makina-corpus

Ou comment gérer les composants natifs par plateforme ?

Nous avons déjà découvert React Native ensemble.

Aujourd'hui on va voir comment développer un menu React Native cross platform pour une application simple qui aura une page home et une page favoris.

Android et IOs ont leurs propres guidelines. C'est pourquoi tous les composants de React Native ne sont pas cross platform. Par exemple sur Android, on utilise DrawerLayoutAndroid pour afficher un menu, alors que sur iOS on aura plutôt tendance à utiliser le composant TabBarIos. C'est parfait car c'est justement le point que nous allons illustrer ici.

Pour ce faire, nous devons simplement créer 2 composants avec le même nom. Seulement l'extension sera différente.

Menu.android.js

import { DrawerLayoutAndroid } from 'react-native';
var Menu = React.createClass({
[...]
render: function() {
  var navigationView = (
    <View style={[styles.layout]}>
      <View style={[styles.header]}>
        <View style={[styles.headerIcon]}>
          <Icon name="md-bulb" size={60} color="#f1c40f" />
        </View>
      </View>
      <Icon.Button style={[styles.menuItem]} name="md-home"  color='#455A64' backgroundColor="#fff" onPress={this.goHome} borderRadius={0}>
        <Text style={[styles.textItem]}>Home</Text>
      </Icon.Button>
      <Icon.Button style={[styles.menuItem]} name="md-star"  color='#455A64' backgroundColor="#fff" onPress={this.goFavoris} borderRadius={0}>
        <Text style={[styles.textItem]}>Starred</Text>
      </Icon.Button>
    </View>
  );
  return (
    <DrawerLayoutAndroid
      ref={'DRAWER_REF'}
      drawerWidth={300}
      drawerPosition={DrawerLayoutAndroid.positions.Left}
      renderNavigationView={() => navigationView}>
      {this.state.currentView == 'home' ? <ReactNativeView paletteStar={this.state.paletteStar} /> : <Starred selectStar={this.selectStar} /> }
    </DrawerLayoutAndroid>
  );
}
})

Menu.ios.js

import { TabBarIOS } from 'react-native';
[...]
var Bulb = React.createClass({
  render: function() {
  return (
    <TabBarIOS
      unselectedTintColor="yellow"
      tintColor="white"
      barTintColor="#34495e"
      >
      <Icon.TabBarItemIOS
        title="Home"
        iconName="ios-home-outline"
        selectedIconName="ios-home"
        selected={this.state.currentView === 'home'}
        onPress={() => {
          this.setState({
            currentView: 'home',
          });
        }}>
        <ReactNativeView ref={'HOME'} paletteStar={this.state.paletteStar}/>
      </Icon.TabBarItemIOS>
      <Icon.TabBarItemIOS
        title="Starred"
        iconName="ios-star-outline"
        selectedIconName="ios-star"
        selected={this.state.currentView === 'favoris'}
        onPress={() => {
          this.setState({
            currentView: 'favoris'
          });
          this.refs['STARRED'].loadStar();
        }}>
        <Starred ref={'STARRED'} selectStar={this.selectStar} />
      </Icon.TabBarItemIOS>
    </TabBarIOS>
  );
}
})

Gràce à ses extensions (ios.js et android.js), React Native saura qu'il doit utiliser Menu.android.js pour la version android et Menu.ios.js pour iOS.

Notre composant affichera donc selon la plateforme un menu 'TabBar' sur ios et un menu 'Slide' pour android, chacun avec leur propre style.

Des comportements différents

Il faudra faire attention, car justement, ce n'est pas les mêmes composants et donc leurs comportements peut varier.

Ici, lors d'un changement d'option de menu deux scénarios se présentent.

DrawerAndroid : Le composant se recréer à chaque appel, ce qui implique qu'il passera toujours dans notre fonction de cycle de vie ComponentDidMount.

TabBarIos : Les composants ne se rechargent pas chaque fois, ils sont directement créer lors du démarrage de l'application. On ne passera donc pas dans le cycle ComponentDidMount à chaque appel.

Deux choix s'offrent donc à nous, avoir ici aussi un composant home et favoris pour chaque plateforme, ou bien prendre en charge directement dans le composant parent l'action à réaliser lors du changement d'option.

Seulement, l'un des avantages de React Native est justement de pouvoir utiliser le même code pour toutes les plateformes. Du coup, il parait logique d'éviter cette multiplication de composant spécifiques.

Donc dans notre exemple, lors d'un changement d'option sur iOS, on appel directement la fonction du composant enfant pour recharger les favoris : this.refs['STARRED'].loadStar(); Aucune action n'est nécessaire du coté d'Android, car il passera dans ComponentDidMount pour charger les favoris à chaque fois.

On notera que l'on aurait aussi pu utiliser, dans nos composants, le code JS suivant pour gérer nos spécificités :

if (Platform.OS === 'android') {
   ...
} else {

}

De plus, nous aurions pu utiliser Redux, par exemple, pour nos problèmes de chargement de données.

Conclusion

React Native permet donc de créer des pages spécifiques pour chaque plateforme et d'utiliser des composants natifs pour chacun. Tout ceci se fait simplement et rapidement. Le seul détail qui peut prendre un peu de temps est la partie de création du style des menus, en particulier celui de Android. Mais on verra cette partie plus en détail lors d'un prochain article. Pour aller plus loin, n'hésitez pas à suivre notre formation à react Native !

Formations associées

Mobile

React Native

Aucune session de formation n'est prévue pour le moment.

Pour plus d'informations, n'hésitez pas à nous contacter.

Voir la formation

Front-end

ReactJS

Aucune session de formation n'est prévue pour le moment.

Pour plus d'informations, n'hésitez pas à nous contacter.

Voir la formation

Actualités en lien

Image
Logo Cypress
11/10/2021

Retour d’expérience : tests fonctionnels avec Cypress

Dans le cadre d'un de nos projets de développement spécifique, l’équipe Makina Corpus a été amenée à coder un important logiciel métier avec de nombreuses entités et règles de gestion : l’Hydroportail.

Voir l'article
29/03/2019

Des boucles de composants génériques avec Angular

Ou comment faire des composants de listes réutilisables avec n'importe quel objet.

Voir l'article
Image
IA_Angular_Universal
08/10/2018

Mettre en place Angular Universal avec Angular 6 et 7

Le fonctionnement d'Angular Universal expliqué. Toutes les étapes de mise en place détaillées. Les pièges à éviter.

Voir l'article

Inscription à la newsletter

Nous vous avons convaincus