Différences
Ci-dessous, les différences entre deux révisions de la page.
| Les deux révisions précédentes Révision précédente Prochaine révision | Révision précédente | ||
| formations:devmobile_2 [26/09/2021 19:44] – foder | formations:devmobile_2 [18/11/2021 18:36] (Version actuelle) – foder | ||
|---|---|---|---|
| Ligne 1: | Ligne 1: | ||
| + | ====== Dev mobile 102 : Components, Navigation et API ====== | ||
| + | |||
| + | == Prérequis == | ||
| + | |||
| + | Pour suivre cette formation, il faut évidemment avoir suivi la [[formations: | ||
| + | |||
| + | ===== Le projet ===== | ||
| + | |||
| + | Pour avoir un fil conducteur tout au long de ces formations, nous allons créer une application qui pourrait être utile au GInfo : elle permettra aux utilisateurs de laisser un feedback anonyme sur les formations. | ||
| + | |||
| + | ===== Les Components ===== | ||
| + | |||
| + | === C'est quoi un component ? === | ||
| + | |||
| + | Avec cette formation, vous allez découvrir ce qui fait la puissance de React (et que React Native utilise aussi) : les components. Lors de la précédente formation, vous avez probablement entendu ce mot, pour parler des ' | ||
| + | |||
| + | Et la grande force de React, c'est que maintenant, nous allons créer nos propres Component ! Vous pourrez ainsi définir, par exemple, un component '' | ||
| + | |||
| + | Je suis désolé mais en vrai c'est trop stylé. | ||
| + | |||
| + | === Créer un component === | ||
| + | |||
| + | Nous allons créer un premier component. Tout d' | ||
| + | |||
| + | {{: | ||
| + | |||
| + | Ensuite, nous devons importer '' | ||
| + | |||
| + | < | ||
| + | import React from ' | ||
| + | |||
| + | class Home extends React.Component { | ||
| + | |||
| + | } | ||
| + | |||
| + | export default Home; | ||
| + | </ | ||
| + | |||
| + | Les components doivent forcément disposer d'une méthode '' | ||
| + | |||
| + | < | ||
| + | import React from ' | ||
| + | import {View, StyleSheet} from " | ||
| + | |||
| + | class Home extends React.Component { | ||
| + | |||
| + | | ||
| + | return ( | ||
| + | <View style={styles.redView}/> | ||
| + | ) | ||
| + | } | ||
| + | } | ||
| + | |||
| + | const styles = StyleSheet.create({ | ||
| + | redView: { | ||
| + | flex:1, | ||
| + | backgroundColor: | ||
| + | } | ||
| + | }); | ||
| + | |||
| + | export default Home; | ||
| + | </ | ||
| + | |||
| + | On a simplement crée la méthode '' | ||
| + | |||
| + | === Utilisons notre component === | ||
| + | |||
| + | Pour utiliser notre component, nous allons modifier le '' | ||
| + | |||
| + | < | ||
| + | import Home from " | ||
| + | |||
| + | export default function App() { | ||
| + | return ( | ||
| + | <View style={styles.container}> | ||
| + | < | ||
| + | </ | ||
| + | ); | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Et maintenant, quand on lance l' | ||
| + | |||
| + | === Un peu de pratique === | ||
| + | |||
| + | Maintenant, nous allons utiliser ce component '' | ||
| + | |||
| + | {{ : | ||
| + | |||
| + | vous pouvez utiliser cette image de fond : | ||
| + | |||
| + | {{: | ||
| + | |||
| + | Correction : | ||
| + | < | ||
| + | < | ||
| + | import React from ' | ||
| + | import {View, StyleSheet, Image, Text, TouchableOpacity} from " | ||
| + | |||
| + | class Home extends React.Component { | ||
| + | |||
| + | goBtn = () => { | ||
| + | console.log(' | ||
| + | } | ||
| + | |||
| + | render() { | ||
| + | return ( | ||
| + | <View style={styles.redView}> | ||
| + | <Image source={require(' | ||
| + | <View style={styles.titleContainer}> | ||
| + | <View style={styles.title}> | ||
| + | <Text style={styles.titleText}> | ||
| + | </ | ||
| + | </ | ||
| + | <View style={styles.goBtnContainer}> | ||
| + | < | ||
| + | <Text style={styles.goBtnText}> | ||
| + | </ | ||
| + | </ | ||
| + | </ | ||
| + | ) | ||
| + | } | ||
| + | } | ||
| + | |||
| + | const styles = StyleSheet.create({ | ||
| + | redView: { | ||
| + | flex:1, | ||
| + | }, | ||
| + | imgBackG: { | ||
| + | position: ' | ||
| + | top: 0, | ||
| + | left:0, | ||
| + | bottom:0, | ||
| + | right: 0 | ||
| + | }, | ||
| + | titleContainer: | ||
| + | flex: 2, | ||
| + | alignItems: ' | ||
| + | justifyContent: | ||
| + | }, | ||
| + | title: { | ||
| + | backgroundColor: | ||
| + | padding: 20, | ||
| + | margin: 20, | ||
| + | borderRadius: | ||
| + | }, | ||
| + | titleText: { | ||
| + | color: '# | ||
| + | fontSize: 25, | ||
| + | fontWeight: ' | ||
| + | textAlign: ' | ||
| + | }, | ||
| + | goBtnContainer: | ||
| + | flex: 1, | ||
| + | alignItems: ' | ||
| + | justifyContent: | ||
| + | }, | ||
| + | goBtn: { | ||
| + | backgroundColor: | ||
| + | padding: 10, | ||
| + | borderRadius: | ||
| + | elevation: 10, | ||
| + | }, | ||
| + | goBtnText: { | ||
| + | color: '# | ||
| + | fontSize: 20, | ||
| + | fontWeight: ' | ||
| + | } | ||
| + | }); | ||
| + | |||
| + | export default Home; | ||
| + | </ | ||
| + | </ | ||
| + | |||
| + | ===== La Navigation ===== | ||
| + | |||
| + | === De quoi on parle ? === | ||
| + | |||
| + | On vient de créer une page d' | ||
| + | |||
| + | Su un site web, vous vous attendriez à ce que ce bouton vous renvoie vers une autre page. C'est exactement ce que nous voulons faire. Pour cela nous allons utiliser la '' | ||
| + | |||
| + | < | ||
| + | |||
| + | === Créer un Navigator === | ||
| + | |||
| + | Pour implémenter une navigation, nous allons créer un '' | ||
| + | |||
| + | Commençons par créer un dossier '' | ||
| + | |||
| + | {{: | ||
| + | |||
| + | Dedans, nous allons importer les fonctions permettant de créer un '' | ||
| + | |||
| + | < | ||
| + | import {createStackNavigator} from ' | ||
| + | import {createAppContainer} from ' | ||
| + | |||
| + | const AppNavigator = createStackNavigator({}) | ||
| + | |||
| + | export default createAppContainer(AppNavigator); | ||
| + | </ | ||
| + | |||
| + | Maintenant, tout va se passer dans le '' | ||
| + | |||
| + | < | ||
| + | import Home from ' | ||
| + | import FormaList from " | ||
| + | |||
| + | const AppNavigator = createStackNavigator({ | ||
| + | Home: { | ||
| + | screen: Home | ||
| + | }, | ||
| + | FormaList: { | ||
| + | screen: FormaList | ||
| + | } | ||
| + | }) | ||
| + | </ | ||
| + | |||
| + | Et pour utiliser cette navigation dans l' | ||
| + | |||
| + | {{ : | ||
| + | |||
| + | === Naviguons === | ||
| + | |||
| + | Jusqu' | ||
| + | |||
| + | Tout d' | ||
| + | |||
| + | < | ||
| + | goBtn() { | ||
| + | console.log(' | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Comme ça, lorsqu' | ||
| + | |||
| + | < | ||
| + | goBtn = () => { | ||
| + | console.log(' | ||
| + | this.props.navigation.navigate(' | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Et quand on clique... TADAAMMM ! On arrive sur une vue toute rouge, avec ' | ||
| + | |||
| + | {{ : | ||
| + | |||
| + | ===== Se connecter à une API Web ===== | ||
| + | |||
| + | === Rappel des objectifs === | ||
| + | |||
| + | Le projet est de faire une application permettant aux utilisateurs d' | ||
| + | |||
| + | Cela nécessite de partager un certain nombre de données entre les différent utilisateurs : les formations, les sessions, et les commentaires. Autrement dit, nous avons besoin d'un back-end. Étant donné que ce n'est pas le sujet de cette formation, nous avons développé le back-end, qui est acessible à l' | ||
| + | |||
| + | * ''/ | ||
| + | * ''/ | ||
| + | * ''/ | ||
| + | * ''/ | ||
| + | * ''/ | ||
| + | * ''/ | ||
| + | |||
| + | Et une autre route pour l' | ||
| + | |||
| + | === fetch === | ||
| + | |||
| + | La prochaine étape pour l' | ||
| + | |||
| + | < | ||
| + | loadFormas() { | ||
| + | fetch(' | ||
| + | return response.json() | ||
| + | }).then((data) => { | ||
| + | console.log(data[0]); | ||
| + | }) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Cette fonction va simplement récupérer la liste des formations, et afficher la première dans la console. Avec '' | ||
| + | |||
| + | {{: | ||
| + | |||
| + | Cette liste de formation qu'on récupère, il va aussi falloir la stocker. On va donc ajouter des attributs à notre component : '' | ||
| + | |||
| + | < | ||
| + | constructor(props) { | ||
| + | super(props); | ||
| + | this.formas = []; | ||
| + | this.isLoading = true; | ||
| + | } | ||
| + | |||
| + | loadFormas() { | ||
| + | if(this.isLoading){ | ||
| + | fetch(' | ||
| + | return response.json() | ||
| + | }).then((data) => { | ||
| + | this.formas = data | ||
| + | this.isLoading = false | ||
| + | setTimeout(() => {this.forceUpdate()}, | ||
| + | }) | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | À quoi sert l' | ||
| + | |||
| + | < | ||
| + | displayLoading() { | ||
| + | return ( | ||
| + | <View style={styles.redView}> | ||
| + | < | ||
| + | </ | ||
| + | ) | ||
| + | } | ||
| + | |||
| + | displayFormas() { | ||
| + | return ( | ||
| + | <View style={styles.blueView} /> | ||
| + | ) | ||
| + | } | ||
| + | |||
| + | render() { | ||
| + | this.loadFormas() | ||
| + | return ( | ||
| + | <View style={styles.mainContainer}> | ||
| + | {this.isLoading ? this.displayLoading() : this.displayFormas()} | ||
| + | </ | ||
| + | ) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Avec tout ce code, voilà ce qu'il se passe lorsqu' | ||
| + | - Le '' | ||
| + | - La méthode '' | ||
| + | - La méthode '' | ||
| + | - '' | ||
| + | - Après 1 seconde donc, le '' | ||
| + | - '' | ||
| + | |||
| + | Vous avez tout compris ? Cool. Maintenant, on va afficher ces formations ! | ||
| + | |||
| + | === Une FlatList === | ||
| + | |||
| + | Les '' | ||
| + | |||
| + | < | ||
| + | displayFormas() { | ||
| + | return ( | ||
| + | < | ||
| + | < | ||
| + | data={this.formas} | ||
| + | keyExtractor={(item) => item.id.toString()} | ||
| + | renderItem={({item}) => < | ||
| + | /> | ||
| + | </ | ||
| + | ) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | On a mis une '' | ||
| + | |||
| + | < | ||
| + | <Text style={styles.titleText}> | ||
| + | </ | ||
| + | |||
| + | Le component en entier si vous avez pas le temps, pour voir ce que ça peut donner : | ||
| + | |||
| + | < | ||
| + | < | ||
| + | class FormaItem extends React.Component { | ||
| + | |||
| + | render() { | ||
| + | return ( | ||
| + | <View style={styles.redView}> | ||
| + | <Image | ||
| + | source={{uri:' | ||
| + | style={styles.imgForma} | ||
| + | /> | ||
| + | <View style={styles.titleView}> | ||
| + | <Text style={styles.titleText}> | ||
| + | </ | ||
| + | </ | ||
| + | ) | ||
| + | } | ||
| + | } | ||
| + | |||
| + | const styles = StyleSheet.create({ | ||
| + | redView: { | ||
| + | backgroundColor: | ||
| + | alignItems: ' | ||
| + | flexDirection: | ||
| + | padding: 10, | ||
| + | margin: 10 | ||
| + | }, | ||
| + | imgForma: { | ||
| + | height: 100, | ||
| + | width: 100, | ||
| + | backgroundColor: | ||
| + | }, | ||
| + | titleView: { | ||
| + | marginLeft: 50 | ||
| + | }, | ||
| + | titleText: { | ||
| + | color: '# | ||
| + | fontSize: 25, | ||
| + | fontWeight: ' | ||
| + | textAlign: ' | ||
| + | }, | ||
| + | }); | ||
| + | </ | ||
| + | </ | ||
| + | |||
| + | On obtiens quelque chose comme ça : | ||
| + | |||
| + | {{ : | ||
| + | |||
| + | ===== Pratiquez ! ===== | ||
| + | |||
| + | L' | ||
| + | |||
| + | {{: | ||
| + | ---- | ||
| + | {{: | ||
| + | |||
| + | [[https:// | ||