Accueil / Blog / Métier / 2016 / Créer un menu natif crossplatform avec React Native

Créer un menu natif crossplatform avec React Native

Par Bastien Alvez — publié 20/07/2016, édité le 23/07/2018
Ou comment gérer les composants natifs par plateforme ?
Créer un menu natif crossplatform avec React Native

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 !

ABONNEZ-VOUS À LA NEWSLETTER !
Voir aussi
React 16.3 : Introduction de la context API React 16.3 : Introduction de la context API 06/04/2018

React 16.3 apporte son lot de nouveautés, mais surtout la version stable de la context API.

Découverte de React Native Découverte de React Native 18/04/2016

Présentation de React Native, quelles sont ses possibilités et peut-on l'utiliser en prod ?

PWA : Atteindre un score élevé dans Google Lighthouse avec Ionic 2 PWA : Atteindre un score élevé dans Google Lighthouse avec Ionic 2 30/03/2017

Quelques astuces pour créer une Progressive Web App de qualité avec Ionic 2.

Bien démarrer avec Ionic Bien démarrer avec Ionic 07/12/2015

Une ressource pour les développeurs Ionic et ceux qui veulent démarrer dans le développement ...

Retour sur le petit déjeuner "Quel framework JS pour 2017 ?" Retour sur le petit déjeuner "Quel framework JS pour 2017 ?" 09/12/2016

Si vous n'avez pas pu assister à notre session toulousaine ou à notre session nantaise, voici la ...