Fondamentaux de React Native

I. Programme de base :

import React, { Component } from 'react';
import { Text } from 'react-native';

export default class HelloWorldApp extends Component {
  render() {
    return (
      <Text>Bonjour le monde !</Text>
    );
  }
}

Explication du programme de base :

  • Maîtriser ES2015, les nouvelles syntaxes comme import, from, class, extends, et les fonctions fléchées () => sont des fonctionnalités d'ES2015. Si vous n'êtes pas familier avec ES2015, consultez le livre de Ruanyifeng ou ce résumé du forum.
  • <Text>Bonjour le monde !</Text> - C'est ce qu'on appelle JSX, une syntaxe permettant d'intégrer des structures XML dans JavaScript. Bien que cela ressemble à HTML, il s'agit en réalité du composant <TEXT> de React Native. Plus de composants disponibles.
  • Le code ci-dessus définit un nouveau composant nommé HelloWorldApp. Dans les applications React Native, vous créerez de nombreux composants. L'interface finale d'une application est constituée de combinaisons de ces composants. La structure d'un composant peut être simple – la seule exigence est de retourner du JSX dans la méthode render.

II. Concepts clés

1. Propriétés (Props)

Prenons l'exemple du composant de base Image. Pour afficher une image, vous pouvez passer une propriété appelée source pour spécifier l'adresse de l'image, ainsi qu'une propriété style pour contrôler ses dimensions.

// Propriétés standards
import React, { Component } from 'react';
import { Image } from 'react-native';

export default class Bananas extends Component {
  render() {
    let pic = {
      uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
    };
    return (
      <Image source={pic} style={{width: 193, height: 110}} />
    );
  }
}

// Propriétés personnalisées
import React, { Component } from 'react';
import { Text, View } from 'react-native';

class Greeting extends Component {
  render() {
    return (
      <Text>Bonjour {this.props.name} !</Text>
    );
  }
}

export default class LotsOfGreetings extends Component {
  render() {
    return (
      <View style={{alignItems: 'center'}}>
        <Greeting name='Rexxar' />
        <Greeting name='Jaina' />
        <Greeting name='Valeera' />
      </View>
    );
  }
}

L'exemple ci-dessus introduit également un nouveau composant appelé View. Le composant View est souvent utilisé comme conteneur pour d'autres composants afin de contrôler leur disposition et leur style.

2. États (State)

Nous utilisons deux types de données pour gérer un composant : props et state. Les props sont définies dans le composant parent et ne chanegnt plus pendant le cycle de vie du composant. Pour les données qui peuvent changer, nous utilisons state.

Imaginons que nous voulions créer un texte clignotant. Le contenu du texte est fixé au moment de la création du composant, donc il doit être une prop. L'état d'affichage ou de masquage du texte (qui crée l'effet de clignotement) change avec le temps, donc cet état doit être stocké dans state.

import React, { Component } from 'react';
import { Text, View } from 'react-native';

class Blink extends Component {
  constructor(props) {
    super(props);
    this.state = { showText: true };

    // Changer l'état toutes les secondes
    setInterval(() => {
      this.setState(previousState => {
        return { showText: !previousState.showText };
      });
    }, 1000);
  }

  render() {
    let display = this.state.showText ? this.props.text : ' ';
    return (
      <Text>{display}</Text>
    );
  }
}

export default class BlinkApp extends Component {
  render() {
    return (
      <View>
        <Blink text='J\'aime clignoter' />
        <Blink text='Oui, clignoter, c\'est formidable' />
        <Blink text='Pourquoi ont-ils supprimé cela de HTML ?' />
        <Blink text='Regardez-moi, regardez-moi, regardez-moi' />
      </View>
    );
  }
}

3. Styles

Dans les applications réelles, les styles des composants deviennent rapidement complexes. Nous recommandons d'utiliser StyleSheet.create pour définir les styles de manière centralisée.

import React, { Component } from 'react';
import { AppRegistry, StyleSheet, Text, View } from 'react-native';

class LotsOfStyles extends Component {
  render() {
    return (
      <View>
        <Text style={styles.red}>rouge uniquement</Text>
        <Text style={styles.bigblue}>bleu foncé uniquement</Text>
        <Text style={[styles.bigblue, styles.red]}>bleu foncé puis rouge</Text>
        <Text style={[styles.red, styles.bigblue]}>rouge puis bleu foncé</Text>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  bigblue: {
    color: 'blue',
    fontWeight: 'bold',
    fontSize: 30,
  },
  red: {
    color: 'red',
  },
});

AppRegistry.registerComponent('LotsOfStyles', () => LotsOfStyles);

Les propriétés déclarées après écraseront celles déclarées avant si elles portent le même nom.

4. Hauteur et largeur

1. Définir les dimensions :

La façon la plus simple de donner une taille à un composant est d'utiliser les styles width et height avec des valeurs fixes. Dans React Native, les dimensions sont exprimées en pixels logiques indépendants de la densité de pixels de l'appareil.

import React, { Component } from 'react';
import { AppRegistry, View } from 'react-native';

class FixedDimensionsBasics extends Component {
  render() {
    return (
      <View>
        <View style={{width: 50, height: 50, backgroundColor: 'powderblue'}} />
        <View style={{width: 100, height: 100, backgroundColor: 'skyblue'}} />
        <View style={{width: 150, height: 150, backgroundColor: 'steelblue'}} />
      </View>
    );
  }
};

AppRegistry.registerComponent('AwesomeProject', () => FixedDimensionsBasics);

2. Dimensions flexibles :

Généralement, utiliser flex:1 permet à un composant de s'étendre pour occuper tout l'espace disponible. Si plusieurs enfants utilisent flex:1, ils partageront l'espace restant de manière équitable. Si leurs valeurs flex sont différentes, celui avec la valeur la plus élevée prendra une proportion plus grande de l'espace restant.

Un composant peut s'étendre seulement si son conteneur parent a une taille non nulle. Sinon, l'espace restant sera nul et les composants enfants utilisant flex ne seront pas visibles.

import React, { Component } from 'react';
import { AppRegistry, View } from 'react-native';

class FlexDimensionsBasics extends Component {
  render() {
    return (
      <View style={{flex: 1}}>
        <View style={{flex: 1, backgroundColor: 'powderblue'}} />
        <View style={{flex: 2, backgroundColor: 'skyblue'}} />
        <View style={{flex: 3, backgroundColor: 'steelblue'}} />
      </View>
    );
  }
};

AppRegistry.registerComponent('AwesomeProject', () => FlexDimensionsBasics);

III. Utilisation de Flexbox pour la mise en page

Nous utilisons les règles de flexbox dans React Native pour organiser les sous-composants d'un composant. Flexbox permet une structure de mise en page cohérente sur différents écrans.

Généralement, les propriétés de style flexDirection, alignItems et justifyContent suffisent pour la plupart des besoins en mise en page. Note : Une illustration simplifiée de la mise en page est disponible pour mieux comprendre.

Le fonctionnement de Flexbox dans React Native est similaire à CSS sur le web, mais avec quelques différences. Par exemple, la valeur par défaut de flexDirection est column au lieu de row, et flex ne peut prendre qu'une seule valeur numérique.

IV. Gestion des entrées texte

TextInput est un composant de base permettant aux utilisateurs de saisir du texte. Il dispose d'une propriété onChangeText qui accepte une fonction exécutée lorsque le texte change. Une autre propriété onSubmitEditing est appelée après soumission du texte (en appuyant sur le bouton "Entrée" du clavier).

Supposons que nous voulions traduire en temps réel chaque mot saisi vers une autre langue, par exemple un seul mot de planète : 🍕. Alors "Bonjour mon ami Bob" serait traduit en "🍕🍕🍕".

import React, { Component } from 'react';
import { AppRegistry, Text, TextInput, View } from 'react-native';

class PizzaTranslator extends Component {
  constructor(props) {
    super(props);
    this.state = {text: ''};
  }

  render() {
    return (
      <View style={{padding: 10}}>
        <TextInput
          style={{height: 40}}
          placeholder="Tapez ici pour traduire !"
          onChangeText={(text) => this.setState({text})}
        />
        <Text style={{padding: 10, fontSize: 42}}>
          {this.state.text.split(' ').map((word) => word && '🍕').join(' ')}
        </Text>
      </View>
    );
  }
}

AppRegistry.registerComponent('PizzaTranslator', () => PizzaTranslator);

Dans l'exemple ci-dessus, nous stockons text dans l'état car il change avec le temps.

Il existe d'autres aspects à gérer dans les champs de saisie. Vous pouvez valider l'entrée utilisateur, voir les exemples détaillés dans la section "Composants de formulaire contrôlés" de React (notez que onChange dans React correspond à onChangeText dans RN). Consultez également la documentation de TextInput.

TextInput est probablement le comopsant le plus simple ayant un "état dynamique". Voyons maintenant un autre type de composant pour contrôler la disposition : ScrollView.

V. Utilisation du composant ScrollView

ScrollView est un conteneur scrollable général. Vous pouvez y placer plusieurs composants et vues, sans restriction sur leur type. ScrollView permet le défilement vertical et horizontal (via la propriété horizontal).

L'exemple suivant montre un ScrollView vertical avec des images et des textes.

import React, { Component } from 'react';
import{ ScrollView, Image, Text, View } from 'react-native'

export default class IScrolledDownAndWhatHappenedNextShockedMe extends Component {
  render() {
      return(
        <ScrollView>
          <Text style={{fontSize:96}}>Défilez-moi</Text>
          <Image source={require('./img/favicon.png')} />
          <Image source={require('./img/favicon.png')} />
          <Image source={require('./img/favicon.png')} />
          <Image source={require('./img/favicon.png')} />
          <Image source={require('./img/favicon.png')} />
          <Text style={{fontSize:96}}>Si vous aimez</Text>
          <Image source={require('./img/favicon.png')} />
          <Image source={require('./img/favicon.png')} />
          <Image source={require('./img/favicon.png')} />
          <Image source={require('./img/favicon.png')} />
          <Image source={require('./img/favicon.png')} />
          <Text style={{fontSize:96}}>Défiler</Text>
          <Image source={require('./img/favicon.png')} />
          <Image source={require('./img/favicon.png')} />
          <Image source={require('./img/favicon.png')} />
          <Image source={require('./img/favicon.png')} />
          <Image source={require('./img/favicon.png')} />
          <Text style={{fontSize:96}}>Quel est le meilleur</Text>
          <Image source={require('./img/favicon.png')} />
          <Image source={require('./img/favicon.png')} />
          <Image source={require('./img/favicon.png')} />
          <Image source={require('./img/favicon.png')} />
          <Image source={require('./img/favicon.png')} />
          <Text style={{fontSize:96}}>Framework autour ?</Text>
          <Image source={require('./img/favicon.png')} />
          <Image source={require('./img/favicon.png')} />
          <Image source={require('./img/favicon.png')} />
          <Image source={require('./img/favicon.png')} />
          <Image source={require('./img/favicon.png')} />
          <Text style={{fontSize:80}}>React Native</Text>
        </ScrollView>
    );
  }
}

À continuer : ScrollView est adopté à un nombre limité d'éléments. Tous les composants sont rendus immédiatement, même s'ils sont hors champ. Pour des listes longues, utilisez plutôt ListView pour de meilleures performances. Voyons comment l'utiliser.

VI. Utilisation des listes longues

React Native propose plusieurs composants pour afficher des listes longues, généralement FlatList ou SectionList.

FlatList est utilisé pour afficher une liste verticale où les éléments sont similaires mais diffèrent par leurs données.

FlatList est plus efficace pour les grandes listes. Contrairement à ScrollView, FlatList ne rend pas tous les éléments à la fois, mais uniquement ceux visibles à l'écran.

Les deux propriétés obligatoires de FlatList sont data et renderItem. data est la source de données, renderItem transforme chaque élément en composant à afficher.

import React, { Component } from 'react';
import { FlatList, StyleSheet, Text, View } from 'react-native';

export default class FlatListBasics extends Component {
  render() {
    return (
      <View style={styles.container}>
        <FlatList
          data={[
            {key: 'Devin'},
            {key: 'Jackson'},
            {key: 'James'},
            {key: 'Joel'},
            {key: 'John'},
            {key: 'Jillian'},
            {key: 'Jimmy'},
            {key: 'Julie'},
          ]}
          renderItem={({item}) => <Text style={styles.item}>{item.key}</Text>}
        />
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
   flex: 1,
   paddingTop: 22
  },
  item: {
    padding: 10,
    fontSize: 18,
    height: 44,
  },
})

Pour les données groupées avec des en-têtes, SectionList est une bonne solution.

import React, { Component } from 'react';
import { SectionList, StyleSheet, Text, View } from 'react-native';

export default class SectionListBasics extends Component {
  render() {
    return (
      <View style={styles.container}>
        <SectionList
          sections={[
            {title: 'D', data: ['Devin']},
            {title: 'J', data: ['Jackson', 'James', 'Jillian', 'Jimmy', 'Joel', 'John', 'Julie']},
          ]}
          renderItem={({item}) => <Text style={styles.item}>{item}</Text>}
          renderSectionHeader={({section}) => <Text style={styles.sectionHeader}>{section.title}</Text>}
        />
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
   flex: 1,
   paddingTop: 22
  },
  sectionHeader: {
    paddingTop: 2,
    paddingLeft: 10,
    paddingRight: 10,
    paddingBottom: 2,
    fontSize: 14,
    fontWeight: 'bold',
    backgroundColor: 'rgba(247,247,247,1.0)',
  },
  item: {
    padding: 10,
    fontSize: 18,
    height: 44,
  },
})

Une utilisation courante des listes est de récupérer des données depuis un serveur. Pour cela, vous devez aussi maîtriser les méthodes réseau de React Native.

VII. Réseau (Référence : http://reactnative.cn/docs/0.51/network.html#content)

Beaucoup d'applications mobiles doivent obtenir des données ou des ressources depuis des adresses distantes. Vous pouvez envoyer des requêtes POST à des API REST, ou simplement récupérer du contenu statique depuis un serveur. Voici les outils nécessaires. Les débutants peuvent consulter ce tutoriel vidéo pour approfondir leur compréhension.

1. Utiliser Fetch

2. Utiliser d'autres bibliothèques réseau

3. Support WebSocket

VIII. Ressources supplémentaires

Outils courants :

  1. Expo :
    • expo diagnostics pour vérifier les versions et diagnostiquer l'environnement ;

Étiquettes: React Native JavaScript mobile development flexbox Component

Publié le 6 octobre à 00h03