React Native avec TypeScript et Expo

Adalbert Pungu
13 min readAug 2, 2023

--

Bonjour j’espère que vous allez bien, Moi c’est Adalbert, un passionné de la technologie et Je suis un grand fan de TypeScript. Je vais vous montrer comment créer cette application Todo List en utilisant React Native avec TypeScript et Expo.

Si vous êtes dans une université, un débutant, ou vous apprenez seul la programmation ou encore un développeur React, ne vous inquiétez pas, je veux montrer les choses étape par étape et vous guider à travers chaque partie du processus. Nous allons créer une application qui permettra à l’utilisateur de gérer une liste de tâches à faire puis affiche l’heure et la date, vous pouvez aussi ajouter, modifier et supprimer de tâches.

Image fetch-app-development
Image fetch-app-development

Choix de l’environnement de travail

En suivant les étapes ci-dessous vous permettra de savoir comment démarrer un Projet avec React Native mais moi je veux utiliser un outil en ligne qui s’appel snack.expo.dev(Expo).

Pour commencer rassurez-vous d’avoir Node.js installé sur votre ordinateur. Ensuite, installez Expo avec la commande suivante dans votre terminal :

npm install -g expo-cli

Initialisation du projet Expo

Nous allons créer un nouveau projet Expo en utilisant la commande suivante dans votre terminal :

expo init TodoListApp

Sélectionnez un template de projet vide (“blank”) lorsqu’on vous le demande. Accédez ensuite au dossier du projet en utilisant la commande cd TodoListApp.

Installation des dépendances

Vous aurez besoin de certaines dépendances pour cette application, accédez dans le dossier du projet avec votre Terminal puis installez les dépendances ci-dessous :

npm install @react-navigation/native @react-navigation/stack
npm install react-native-reanimated react-native-gesture-handler react-native-screens react-native-safe-area-context @react-native-community/masked-view
npm install typescript @types/react @types/react-native

Ces dépendances vont permettre d’utiliser la Navigation pour naviguer entre les différentes vues de l’application, ainsi que TypeScript pour ajouter du typage statique au code et des tout ses avantages qu’offre ce sur-ensemble JavaScript.

Mais sur https://snack.expo.dev/ en ligne on peut ou ne pas vous demander de les installer et il suffit de modifiez le fichier App.js à App.tsx ça va fonctionner.

Utilisation d’Expo en ligne

Pour cette application nous allons utiliser Expo en ligne qui est une solution près à l’emploi pour la création des applications simple en React Native mais pour des projets complexes c’est recommandé d’utiliser un environnement de développement approprié (IDE) comme WebStorm mais je vous recommande d’utilisés Visual Studio Code (VS code) qui est un éditeur de texte réputé par sa facilité d’utilisation, sa légèreté et tout ce qui offrent comme fonctionnalité qui lui permet d’être considéré comme un IDE.

Allons-y sur la plate-forme https://snack.expo.dev/ pour débuter la création de l'application et une fois sur le portail vous aurez déjà un projet de départ, puis il suffit de vous connecter ou créer un compte si vous n'avez pas pour que le projet soit enregistré sur votre compte.

Image Portail Snack Expo Dev
Image Portail Snack Expo Dev

Commençons le codage

Modifiez le fichier App.js à App.tsx, nous allons créer le composant principal TodoList pour afficher la liste des tâches et gérer tout ce qui comme opérations ajout des tâches, suppression des tâches, etc.

Avant allez plus loin, vous avez le choix soit de commencer appliqué des modifications, ou d’effacer les codes existants et commencé de développement.

Ajouter ces importations dans le fichier App.tsx qu’on vient de modifier

import React, { useState } from 'react';
import {
View,
Text,
TextInput,
TouchableOpacity,
StyleSheet,
FlatList,
KeyboardAvoidingView,
Platform,
} from 'react-native';

Nous venons importer les composants nécessaires de React Native et React pour construire l’interface utilisateur. React permet de créer des composants fonctionnels en utilisant des Hooks, et React Native nous fournit des composants d’interface utilisateur spécifiques pour les applications Mobiles, IOS, Web.

Composant

Si vous travaillez en ligne comme moi avec Expo vous n’allez pas trop faire des gymnastique il suffit de continuer avec le composant App pour la suite de cet article, mais vous pouvez le faire selon vos préférences, sans oublier que Snack Expo Dev démarre l’application que sur le composant App.

Appliqu’on des modifications au composant App pour afficher le tire.

import React, { useState } from 'react';
import {
View,
Text,
TextInput,
TouchableOpacity,
StyleSheet,
FlatList,
KeyboardAvoidingView,
Platform,
} from 'react-native';

const App: React.FC = () => {
return (
<KeyboardAvoidingView
style={styles.container}
behavior={Platform.OS === 'ios' ? 'padding' : undefined}
>
<Text style={styles.title}>Todo List Test</Text>

</KeyboardAvoidingView>
);
};

// Styles
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
padding: 20,
paddingTop: 50,
},
title: {
fontSize: 24,
fontWeight: 'bold',
marginBottom: 20,
textAlign: 'center',
}
});

export default App;

En React il y a deux type des fonctions, le composant de type classe et de type fonction qu’on appelle composant fonctionnelle. Le composant App est défini comme un composant React fonctionnelle (React.FC).

Création d’une Interface

Les interfaces en TypeScript permettent de définir la forme des objets et d’ajouter des annotations de type. Cela va servir à vérifier le typage et éviter les erreurs lors du développement.

Créons une interface en ajoutant le code ci-dessous pour décrire la structure d’une tâche. Chaque tâche possède un identifiant (id), un texte descriptif (texte) et une date (date).

interface Task {
id: string;
text: string;
date: string;
}

L’interface Task permettra de décrire le modèle de chaque tâche dans l’application. Une tâche aura un id unique et du texte représentant le contenu de la tâche.

import React, { useState } from 'react';
import {
View,
Text,
TextInput,
TouchableOpacity,
StyleSheet,
FlatList,
KeyboardAvoidingView,
Platform,
} from 'react-native';

// Définition de la structure d'une tâche
interface Task {
id: string;
text: string;
date: string;
}

const App: React.FC = () => {
// Initialisation des états
const [tasks, setTasks] = useState<Task[]>([]);
const [taskInput, setTaskInput] = useState<string>('');
const [editingTaskID, setEditingTaskID] = useState<string | null>(null);

return (
<KeyboardAvoidingView
style={styles.container}
behavior={Platform.OS === 'ios' ? 'padding' : undefined}
>
<Text style={styles.title}>Todo List Test</Text>

</KeyboardAvoidingView>
);
};

// Styles
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
padding: 20,
paddingTop: 50,
},
title: {
fontSize: 24,
fontWeight: 'bold',
marginBottom: 20,
textAlign: 'center',
}
});

export default App;

Comme vous voyez très bien, dans cette fonction, mais … Quoi. Oui j’ai bien du fonction. un composant est une fonction et je viens d’ajouter le Hook useState pour déclarer les variables états qui gérons le comportement de l’application, comme stocker la liste des tâches, stocker la tâche en cours d’édition ainsi que l’id de la tâche en cours d’édition.

Task[] : est un tableau d’objets de type Task. TypeScript permet de définir des types pour les variables, ce qui peut améliorer la sécurité et la lisibilité du code. string | null : indique que editingTaskID peut être soit une chaîne de caractères, soit null on appelle union type ou annotation de type en TypeScript.

En faite, la principale différence qui est entre le JavaScript et TypeScript réside dans la déclaration et la spécification des types. TypeScript ajoute une couche de sécurité en détectant les erreurs de type potentielles avant l’exécution du code. Cela permet de réduire les bugs liés aux types et d’améliorer la maintenabilité du code.

Les Hooks offre une façon d’utiliser l’état local, les contextes et les cycles de vie dans les composants fonctionnels.

// Fonction pour ajouter une nouvelle tâche
const addTask = () => {
if (taskInput.trim() !== '') {
const newTask: Task = {
id: Date.now().toString(),
text: taskInput,
date: new Date().toLocaleString(),
};

setTasks([...tasks, newTask]);
setTaskInput('');
}
};

La fonction addTask permet d’ajouter une nouvelle tâche à la liste des tâches. Elle est déclenchée lorsque l’utilisateur appuie sur le bouton “Ajouter”.

  • Nous vérifions d’abord si la chaîne taskInput n’est pas vide (trim() supprime les espaces vides au début et à la fin de la chaîne).
  • Si la chaîne n’est pas vide, nous créons un nouvel objet task avec l’id généré par la fonction Date.now().toString() et le texte de la nouvelle tâche.
  • Nous utilisons la fonction setTasks pour mettre à jour l’état tasks en ajoutant la nouvelle tâche à la liste.
  • Puis setTaskInput pour réinitialiser la variable taskInput à une chaîne vide, afin de vider le champ de saisie.

Ajoutez un autre fonction qui va servir a supprimer des tâches

// Fonction pour supprimer une tâche
const deleteTask = (id: string) => {
const filteredTasks = tasks.filter((task) => task.id !== id);
setTasks(filteredTasks);
};

La fonction deleteTask qui va permettre de la supprimer des tâches, elle est déclenchée lorsque l’utilisateur appuie sur le bouton “Supprimer”.

  • La fonction prend l’id de la tâche à supprimer en tant que paramètre.
  • Nous utilisons la méthode filter pour créer un nouveau tableau filteredTasks, qui contient toutes les tâches sauf celle avec l’id spécifié.
  • setTasks met à jour l’état tasks avec le nouveau tableau filteredTasks, ce qui aura pour effet de supprimer la tâche de la liste.

Ajouter la fonction pour modifier le texte d’une tâche :

const editTask = (id: string, newText: string) => {
const updatedTasks = tasks.map((task) => {
if (task.id === id) {
return { ...task, text: newText };
}
return task;
});
setTasks(updatedTasks);
setEditingTaskID(null);
};

voici jusqu’à présent a quoi ressemble le code l’application

import React, { useState } from 'react';
import {
View,
Text,
TextInput,
TouchableOpacity,
StyleSheet,
FlatList,
KeyboardAvoidingView,
SafeAreaView,
Platform,
} from 'react-native';

// Définition de la structure d'une tâche
interface Task {
id: string;
text: string;
date: string;
}

const App: React.FC = () => {
// Initialisation des états
const [tasks, setTasks] = useState<Task[]>([]);
const [taskInput, setTaskInput] = useState<string>('');
const [editingTaskID, setEditingTaskID] = useState<string | null>(null);

// Fonction pour ajouter une nouvelle tâche
const addTask = () => {
if (taskInput.trim() !== '') {
const newTask: Task = {
id: Date.now().toString(),
text: taskInput,
date: new Date().toLocaleString(),
};

setTasks([...tasks, newTask]);
setTaskInput('');
}
};

// Fonction pour supprimer une tâche
const deleteTask = (id: string) => {
const filteredTasks = tasks.filter((task) => task.id !== id);
setTasks(filteredTasks);
};

//Fonction pour modifier le texte d'une tâche
const editTask = (id: string, newText: string) => {
const updatedTasks = tasks.map((task) => {
if (task.id === id) {
return { ...task, text: newText };
}
return task;
});
setTasks(updatedTasks);
setEditingTaskID(null);
};

return (
<KeyboardAvoidingView
style={styles.container}
behavior={Platform.OS === 'ios' ? 'padding' : undefined}
>
<Text style={styles.title}>Todo List Test</Text>
<FlatList
data={tasks}
//renderItem={renderTask}
keyExtractor={(item: { id: any; }) => item.id}
style={styles.taskList}
/>
<View style={styles.inputContainer}>
<TextInput
style={styles.input}
value={taskInput}
onChangeText={(text: string) => setTaskInput(text)}
placeholder="Enter a new task"
placeholderTextColor="#000"
/>
<TouchableOpacity style={styles.button} onPress={addTask}>
<Text style={styles.buttonText}>Ajouter</Text>
</TouchableOpacity>
</View>

</KeyboardAvoidingView>
);
};

// Styles
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
padding: 20,
paddingTop: 50,
},
title: {
fontSize: 24,
fontWeight: 'bold',
marginBottom: 20,
textAlign: 'center',
},
inputContainer: {
flexDirection: 'row',
marginBottom: 20,
},
input: {
flex: 1,
borderWidth: 1,
borderColor: '#000',
padding: 10,
marginRight: 10,
color: '#000',
},
button: {
backgroundColor: '#000',
padding: 10,
justifyContent: 'center',
alignItems: 'center',
borderRadius: 5,
},
buttonText: {
color: '#fff',
fontWeight: 'bold',
},
taskList: {
flex: 1,
}

});

export default App;

Par ici si vous essayez d’entrer une tâche, elle ne sera pas affichée parce qu’il faut ajouter une fonction pour afficher les tâches et retourner l’interface utilisateur de l’application, ce qui va permettre à une tâche d’apparaitre sur l’écran.

// Fonction pour afficher une tâche dans la liste
const renderTask = ({ item }: { item: Task }) => (
<View style={styles.taskItem}>
{editingTaskID === item.id ? (
<TextInput
style={styles.taskTextEdit}
value={taskInput}
onChangeText={(text: React.SetStateAction<string>) => setTaskInput(text)}
/>
) : (
<Text style={styles.taskText}>{item.text}</Text>
)}
<Text style={styles.taskDate}>Date : {item.date}</Text>
<View style={styles.actionsContainer}>
{editingTaskID === item.id ? (
<TouchableOpacity
style={styles.actionButton}
onPress={() => editTask(item.id, taskInput)}
>
<Text style={styles.actionButtonText}>Valider</Text>
</TouchableOpacity>
) : (
<TouchableOpacity
style={styles.actionButton}
onPress={() => setEditingTaskID(item.id)}
>
<Text style={styles.actionButtonText}>Modifier</Text>
</TouchableOpacity>
)}
<TouchableOpacity
style={styles.actionButton}
onPress={() => deleteTask(item.id)}
>
<Text style={styles.actionButtonText}>Supprimer</Text>
</TouchableOpacity>
</View>
</View>
);

return (
<KeyboardAvoidingView
style={styles.container}
behavior={Platform.OS === 'ios' ? 'padding' : undefined}
>
<Text style={styles.title}>Todo List Test</Text>
<FlatList
data={tasks}
renderItem={renderTask}
keyExtractor={(item: { id: any; }) => item.id}
style={styles.taskList}
/>
<View style={styles.inputContainer}>
<TextInput
style={styles.input}
value={taskInput}
onChangeText={(text: string) => setTaskInput(text)}
placeholder="Enter a new task"
placeholderTextColor="#000"
/>
<TouchableOpacity style={styles.button} onPress={addTask}>
<Text style={styles.buttonText}>Ajouter</Text>
</TouchableOpacity>
</View>

</KeyboardAvoidingView>
);

Dans cette partie du code, l’interface utilisateur de l’application utilise des composants React Native tels que View, Text, TextInput, TouchableOpacity et FlatList.

  • View est utilisé comme un conteneur pour envelopper tous les éléments de l’interface utilisateur. Nous appliquons également des styles au conteneur pour définir le fond d’écran et la disposition.
  • Text affiche le titre “Todo List test” en utilisant les styles définis.
  • FlatList est utilisée pour afficher la liste des tâches en utilisant le tableau tasks.
  • La propriété data prend le tableau des tâches, renderItem est une fonction qui permet de rendre chaque élément de la liste en utilisant un élément View avec le texte de la tâche et un bouton “Supprimer”.
  • La propriété keyExtractor définit comment extraire une clé unique pour chaque élément de la liste.
  • TextInput est utilisé pour permettre à l’utilisateur de saisir une nouvelle tâche. La valeur de ce champ de saisie est définie par l’état setTask, et la fonction onChangeText met à jour l’état setTaskInput chaque fois que l’utilisateur modifie le texte.
  • TouchableOpacity est utilisée pour créer le bouton “Ajouter” pour ajouter une nouvelle tâche. Lorsque l’utilisateur appuie sur le bouton, la fonction addTask est déclenchée. il est également utilisée pour créer le bouton “Supprimer” à côté de chaque tâche. Lorsque l’utilisateur appuie sur le bouton, la fonction deleteTask est déclenchée avec l’id de la tâche en tant que paramètre.

Enfin, nous appliquons des styles définis pour chaque élément de l’interface utilisateur.

Il est important de voir l’exécution de l’application lorsqu’on développe ce qui permet de voir l’évolution de tout ce qui est comme modification. Expo offre plusieurs possibilités de compiler l’application, vous pouvez voir le résultat de votre application soit en scannent le code QR, soit en lançant l’émulateur (IOS, Android et web), ou encore vous pouvez le voir depuis votre téléphone.

Moi je veux montrer comment le faire avec un IOS externe mais vous pouvez tester les autres méthodes.

Exécution de l’application sur un téléphone iOS externe

Pour exécuter l’application sur un téléphone iOS externe, nous allons utiliser l’application Expo Go. Elle est disponible sur l’App Store , Play Store et vous permet de prévisualiser les applications Expo en direct. Rassurez-vous que vous êtes connecté sur votre téléphone et ordinateur. Ouvrez l’application Expo Go sur le téléphone.

Si vous n’êtes pas sur l’environnement en ligne, dans votre terminal, exécutez la commande suivante pour démarrer le serveur de développement Expo et choisissez le comment vous souhaitez démarrer application :

expo start

Une fois le serveur de développement démarré, un QR code s’affichera dans le terminal. Scannez le QR code avec l’application Expo Go sur votre téléphone iOS ou même depuis la caméra de votre IOS puis l’application sera chargée dans Expo Go qui l’exécutera sur votre téléphone et vous pourrez voir l’application en direct à chaque fois vous appliquez des modifications.

Avantages d’utiliser Expo

Expo est un framework complet pour le développement d’applications React Native.

Voici quelques avantages d’utiliser Expo :

· Facilité de développement : il facilite le développement d’applications React Native en fournissant un ensemble d’outils et de composants préconstruits, ce qui permet aux développeurs de se concentrer davantage sur la logique de l’application plutôt que sur les configurations techniques.

· Prévisualisation en direct : Avec Expo, vous pouvez prévisualiser instantanément votre application sur un appareil physique en scannant le QR code généré lors du démarrage du serveur de développement.

· Distribution d’application simplifiée : Expo facilite la distribution de votre application à des testeurs ou à des utilisateurs finaux sans passer par l’App Store ou le Google Play Store. Vous pouvez partager votre application en générant un lien Expo, permettant aux utilisateurs de l’ouvrir directement avec l’application Expo Go.

· Accès à de nombreuses bibliothèques et API : Expo propose un grand nombre de bibliothèques et d’API intégrées pour gérer des fonctionnalités courantes telles que la caméra, les notifications push, les géolocalisations, etc.

· Facilité de gestion de versions : Expo facilite la gestion des mises à jour d’application en permettant aux utilisateurs d’obtenir automatiquement la dernière version de votre application sans avoir besoin de la mettre à jour manuellement depuis l’App Store ou le Google Play Store.

Pourquoi J’ai choisi d’utiliser Expo

le choisi d’utiliser Expo pour cet exemple d’application est normal, car il offre une approche rapide et facile pour le développement d’applications React Native, en particulier pour les débutants et pour les projets qui ne nécessitent pas de fonctionnalités spécifiques uniquement disponibles dans des bibliothèques tierces. Expo élimine la nécessité de configurer et de gérer des outils externes tels que Xcode ou Android Studio, ce qui simplifie grandement le processus de développement et de test.

Expo permet également de prévisualiser rapidement l’application sur un appareil physique, ce qui est très pratique pour tester en direct les modifications de code pendant le développement.

De ce fait, il est important de noter qu’Expo en ligne à certaines limitations. Si votre projet nécessite des modules natifs personnalisés ou des fonctionnalités spécifiques qui ne sont pas prises en charge par Expo en ligne, vous devrez éjecter votre projet Expo pour utiliser les outils natifs des IDE comme (VS Code, WebStorm, Xcode et Android Studio) et intégrer manuellement les bibliothèques tierces.

Avec React Native c’est qui est important ce d’avoir une bonne compréhension de React JS puis le reste ce juste apprendre les différents composants de React Native et pour TypeScript il est encore très simple à comprendre pour quelqu’un qui fait du JavaScript mais il a une bonne documentation qui explique clairement tout ce qui est comme concept.

Pour la suite, continuez à explorer et à apprendre, il y a beaucoup des choses à connaître du développement d’applications multiplateforme en React Native.

Voici le lien du code source sur mon https://snack.expo.dev/:

Conclusion

C’est tout, Vous avez créer une application Todo List en React Native avec TypeScript en utilisant Expo en ligne comme environnement de développement pour avoir la possibilité d’exécuter l’application sur le web, sur un téléphone iOS ou Android externe. Avec la possibilité d’ajouter, supprimer et modifier des tâches dans la liste. Bref, Vous venez de voir les bases pour créer une application React Native avec TypeScript en utilisant Expo. TypeScript qui est un sur-ensemble JavaScript qui offre un typage statique qui peut rendre votre code plus sûr et plus facile à maintenir vos projets.

Pour plus d’informations sur React Native, React, TypeScript et Expo, vous pouvez consulter ses liens :

Merci d’avoir lu, Follow me on all socials @AdalbertPungu

--

--

Adalbert Pungu
Adalbert Pungu

Written by Adalbert Pungu

Software Developer 👨🏾‍💻| Microsoft MVP | Technical Writer

No responses yet