Création d'applications mobiles à l'aide de React Native et de WordPress
Publié: 2022-03-10En tant que développeurs Web, vous avez peut-être pensé que le développement d'applications mobiles nécessite une nouvelle courbe d'apprentissage avec un autre langage de programmation. Peut-être que Java et Swift doivent être ajoutés à votre ensemble de compétences pour démarrer avec iOS et Android, et cela pourrait vous enliser.
Mais cet article vous surprend ! Nous allons envisager de créer une application de commerce électronique pour iOS et Android en utilisant la plate-forme WooCommerce comme backend. Ce serait un point de départ idéal pour quiconque souhaite se lancer dans le développement multiplateforme natif.
Une brève histoire du développement multiplateforme
Nous sommes en 2011 et nous voyons le début du développement d'applications mobiles hybrides. Des frameworks comme Apache Cordova, PhoneGap et Ionic Framework émergent lentement. Tout semble bon, et les développeurs Web codent avec impatience les applications mobiles avec leurs connaissances existantes.
Cependant, les applications mobiles ressemblaient toujours à des versions mobiles de sites Web. Pas de conceptions natives comme la conception matérielle d'Android ou le look plat d'iOS. La navigation fonctionnait de la même manière que sur le Web et les transitions n'étaient pas fluides. Les utilisateurs n'étaient pas satisfaits des applications construites à l'aide de l'approche hybride et rêvaient de l'expérience native.
Avance rapide jusqu'en mars 2015, et React Native apparaît sur la scène. Les développeurs peuvent créer des applications multiplateformes véritablement natives à l'aide de React, une bibliothèque JavaScript préférée de nombreux développeurs. Ils peuvent désormais facilement apprendre une petite bibliothèque en plus de ce qu'ils savent avec JavaScript. Forts de ces connaissances, les développeurs ciblent désormais le Web, iOS et Android.
De plus, les modifications apportées au code pendant le développement sont chargées sur les appareils de test presque instantanément ! Cela prenait plusieurs minutes lorsque nous avions un développement natif via d'autres approches. Les développeurs peuvent profiter des commentaires instantanés qu'ils aimaient avec le développement Web.
Les développeurs de React sont plus qu'heureux de pouvoir utiliser les modèles existants qu'ils ont suivis dans une nouvelle plate-forme. En fait, ils ciblent deux autres plateformes avec ce qu'ils connaissent déjà très bien.
Tout cela est bon pour le développement frontal. Mais quels choix avons-nous pour la technologie back-end ? Doit-on encore apprendre un nouveau langage ou framework ?
L'API REST WordPress
Fin 2016, WordPress a publié l'API REST tant attendue et a ouvert les portes à des solutions avec des backends découplés.
Donc, si vous avez déjà un site Web WordPress et WooCommerce et que vous souhaitez conserver exactement les mêmes offres et profils d'utilisateurs sur votre site Web et votre application native, cet article est pour vous !
Hypothèses faites dans cet article
Je vais vous expliquer comment utiliser votre compétence WordPress pour créer une application mobile avec une boutique WooCommerce à l'aide de React Native. L'article suppose :
- Vous êtes familier avec les différentes API WordPress, au moins à un niveau débutant.
- Vous connaissez les bases de React.
- Vous avez un serveur de développement WordPress prêt. J'utilise Ubuntu avec Apache.
- Vous avez un appareil Android ou iOS à tester avec Expo.
Ce que nous allons construire dans ce tutoriel
Le projet que nous allons construire à travers cet article est une application de boutique de mode. L'application aura les fonctionnalités suivantes :
- Page boutique répertoriant tous les produits,
- Page produit unique avec le détail de l'article sélectionné,
- Fonction 'Ajouter au panier',
- Fonction "Afficher les articles dans le panier",
- Fonction « Supprimer l'article du panier ».
Cet article vise à vous inciter à utiliser ce projet comme point de départ pour créer des applications mobiles complexes à l'aide de React Native.
Note : Pour l'application complète, vous pouvez visiter mon projet sur Github et le cloner .
Démarrer avec notre projet
Nous allons commencer à créer l'application conformément à la documentation officielle de React Native. Après avoir installé Node sur votre environnement de développement, ouvrez l'invite de commande et tapez la commande suivante pour installer globalement l'application native Create React.
npm install -g create-react-native-app
Ensuite, nous pouvons créer notre projet
create-react-native-app react-native-woocommerce-store
Cela créera un nouveau projet React Native que nous pourrons tester avec Expo.
Ensuite, nous devrons installer l'application Expo sur notre appareil mobile que nous voulons tester. Il est disponible pour iOS et Android.
Après avoir installé l'application Expo, nous pouvons exécuter npm start sur notre machine de développement.
cd react-native-woocommerce-store npm start
Après cela, vous pouvez scanner le code QR via l'application Expo ou saisir l'URL donnée dans la barre de recherche de l'application. Cela exécutera l'application de base "Hello World" sur le mobile. Nous pouvons maintenant modifier App.js pour apporter des modifications instantanées à l'application exécutée sur le téléphone.
Alternativement, vous pouvez exécuter l'application sur un émulateur. Mais pour des raisons de brièveté et de précision, nous couvrirons son exécution sur un appareil réel.
Ensuite, installons tous les packages requis pour l'application à l'aide de cette commande :
npm install -s axios react-native-htmlview react-navigation react-redux redux redux-thunk
Configurer un site WordPress
Étant donné que cet article concerne la création d'une application React Native, nous n'entrerons pas dans les détails de la création d'un site WordPress. Veuillez vous référer à cet article pour savoir comment installer WordPress sur Ubuntu. Comme l'API REST WooCommerce nécessite HTTPS, veuillez vous assurer qu'elle est configurée à l'aide de Let's Encrypt. Veuillez vous référer à cet article pour un guide pratique.
Nous ne créons pas d'installation WordPress sur localhost puisque nous exécuterons l'application sur un appareil mobile, et aussi puisque HTTPS est nécessaire.
Une fois WordPress et HTTPS configurés avec succès, nous pouvons installer le plugin WooCommerce sur le site.
Après avoir installé et activé le plugin, poursuivez la configuration de la boutique WooCommerce en suivant l'assistant. Une fois l'assistant terminé, cliquez sur "Retourner au tableau de bord".
Vous serez accueilli par une autre invite.
Cliquez sur 'Allons-y' pour 'Ajouter des exemples de produits'. Cela nous fera gagner du temps pour créer nos propres produits à afficher dans l'application.
Fichier de constantes
Pour charger les produits de notre boutique à partir de l'API REST WooCommerce, nous avons besoin des clés appropriées en place dans notre application. A cet effet, nous pouvons avoir un fichier constans.js
.
Créez d'abord un dossier appelé 'src' et créez des sous-dossiers à l'intérieur comme suit :
Maintenant, générons les clés pour WooCommerce. Dans le tableau de bord WordPress, accédez à WooCommerce → Paramètres → API → Clés/Applications et cliquez sur « Ajouter une clé ».
Créez ensuite une clé en lecture seule avec le nom React Native. Copiez la clé consommateur et le secret consommateur dans le fichier constants.js
comme suit :
const Constants = { URL: { wc: 'https://woocommerce-store.on-its-way.com/wp-json/wc/v2/' }, Keys: { ConsumerKey: 'CONSUMER_KEY_HERE', ConsumerSecret: 'CONSUMER_SECRET_HERE' } } export default Constants;
Commencer avec la navigation réactive
React Navigation est une solution communautaire pour naviguer entre les différents écrans et est une bibliothèque autonome. Il permet aux développeurs de configurer les écrans de l'application React Native avec seulement quelques lignes de code.
Il existe différentes méthodes de navigation dans React Navigation :
- Empiler,
- Changer,
- Onglets,
- Tiroir,
- et plus.
Pour notre application, nous utiliserons une combinaison de StackNavigation
et de DrawerNavigation
pour naviguer entre les différents écrans. StackNavigation
est similaire au fonctionnement de l'historique du navigateur sur le Web. Nous l'utilisons car il fournit une interface pour l'en-tête et les icônes de navigation d'en-tête. Il a un push et un pop similaires aux piles dans les structures de données. Pousser signifie que nous ajoutons un nouvel écran en haut de la pile de navigation. Pop supprime un écran de la pile.
Le code montre que le StackNavigation
, en fait, abrite le DrawerNavigation
en lui-même. Il prend également des propriétés pour le style d'en-tête et les boutons d'en-tête. Nous plaçons le bouton du tiroir de navigation à gauche et le bouton du panier à droite. Le bouton du tiroir allume et éteint le tiroir tandis que le bouton du panier amène l'utilisateur à l'écran du panier.
const StackNavigation = StackNavigator({ DrawerNavigation: { screen: DrawerNavigation } }, { headerMode: 'float', navigationOptions: ({ navigation, screenProps }) => ({ headerStyle: { backgroundColor: '#4C3E54' }, headerTintColor: 'white', headerLeft: drawerButton(navigation), headerRight: cartButton(navigation, screenProps) }) }); const drawerButton = (navigation) => ( <Text style={{ padding: 15, color: 'white' }} onPress={() => { if (navigation.state.index === 0) { navigation.navigate('DrawerOpen') } else { navigation.navigate('DrawerClose') } } }> ( <Text style={{ padding: 15, color: 'white' }} onPress={() => { navigation.navigate('CartPage') }} > <EvilIcons name="cart" size={30} /> {screenProps.cartCount} </Text> );
const StackNavigation = StackNavigator({ DrawerNavigation: { screen: DrawerNavigation } }, { headerMode: 'float', navigationOptions: ({ navigation, screenProps }) => ({ headerStyle: { backgroundColor: '#4C3E54' }, headerTintColor: 'white', headerLeft: drawerButton(navigation), headerRight: cartButton(navigation, screenProps) }) }); const drawerButton = (navigation) => ( <Text style={{ padding: 15, color: 'white' }} onPress={() => { if (navigation.state.index === 0) { navigation.navigate('DrawerOpen') } else { navigation.navigate('DrawerClose') } } }> ( <Text style={{ padding: 15, color: 'white' }} onPress={() => { navigation.navigate('CartPage') }} > <EvilIcons name="cart" size={30} /> {screenProps.cartCount} </Text> );
DrawerNavigation
, quant à lui, fournit le tiroir latéral qui nous permettra de naviguer entre la maison, la boutique et le panier. Le DrawerNavigator
répertorie les différents écrans que l'utilisateur peut visiter, à savoir la page d'accueil, la page des produits, la page des produits et la page du panier. Il possède également une propriété qui prendra le conteneur Tiroir : le menu coulissant qui s'ouvre en cliquant sur le menu hamburger.
const DrawerNavigation = DrawerNavigator({ Home: { screen: HomePage, navigationOptions: { title: "RN WC Store" } }, Products: { screen: Products, navigationOptions: { title: "Shop" } }, Product: { screen: Product, navigationOptions: ({ navigation }) => ({ title: navigation.state.params.product.name }), }, CartPage: { screen: CartPage, navigationOptions: { title: "Cart" } } }, { contentComponent: DrawerContainer });
Injection du magasin Redux dans App.js
Puisque nous utilisons Redux dans cette application, nous devons injecter le magasin dans notre application. Nous le faisons à l'aide du composant Provider
.
const store = configureStore(); class App extends React.Component { render() { return ( <Provider store={store}> <ConnectedApp /> </Provider> ) } }
Nous aurons alors un composant ConnectedApp
afin que nous puissions avoir le nombre de paniers dans l'en-tête.
class CA extends React.Component { render() { const cart = { cartCount: this.props.cart.length } return ( <StackNavigation screenProps={cart} /> ); } } function mapStateToProps(state) { return { cart: state.cart }; } const ConnectedApp = connect(mapStateToProps, null)(CA);
Magasin Redux, actions et réducteurs
Dans Redux, nous avons trois parties différentes :
- Boutique
Contient tout l'état de l'ensemble de votre application. La seule façon de changer d'état est de lui envoyer une action. - Actions
Un objet simple qui représente une intention de changer l'état. - Réducteurs
Une fonction qui accepte un état et un type d'action et renvoie un nouvel état.
Ces trois composants de Redux nous aident à atteindre un état prévisible pour l'ensemble de l'application. Pour plus de simplicité, nous verrons comment les produits sont récupérés et enregistrés dans le magasin Redux.
Tout d'abord, regardons le code de création du magasin :
let middleware = [thunk]; export default function configureStore() { return createStore( RootReducer, applyMiddleware(...middleware) ); }
Ensuite, l'action products est responsable de la récupération des produits à partir du site Web distant.
export function getProducts() { return (dispatch) => { const url = `${Constants.URL.wc}products?per_page=100&consumer_key=${Constants.Keys.ConsumerKey}&consumer_secret=${Constants.Keys.ConsumerSecret}` return axios.get(url).then(response => { dispatch({ type: types.GET_PRODUCTS_SUCCESS, products: response.data } )}).catch(err => { console.log(err.error); }) }; }
Le réducteur de produits est chargé de renvoyer la charge utile des données et de déterminer si elle doit être modifiée.
export default function (state = InitialState.products, action) { switch (action.type) { case types.GET_PRODUCTS_SUCCESS: return action.products; default: return state; } }
Affichage de la boutique WooCommerce
Le fichier products.js
est notre page Boutique. Il affiche essentiellement la liste des produits de WooCommerce.
class ProductsList extends Component { componentDidMount() { this.props.ProductAction.getProducts(); } _keyExtractor = (item, index) => item.id; render() { const { navigate } = this.props.navigation; const Items = ( <FlatList contentContainerStyle={styles.list} numColumns={2} data={this.props.products || []} keyExtractor={this._keyExtractor} renderItem={ ({ item }) => ( <TouchableHighlight style={{ width: '50%' }} onPress={() => navigate("Product", { product: item })} underlayColor="white"> <View style={styles.view} > <Image style={styles.image} source={{ uri: item.images[0].src }} /> <Text style={styles.text}>{item.name}</Text> </View> </TouchableHighlight> ) } /> ); return ( <ScrollView> {this.props.products.length ? Items : <View style={{ alignItems: 'center', justifyContent: 'center' }}> <Image style={styles.loader} source={LoadingAnimation} /> </View> } </ScrollView> ); } }
this.props.ProductAction.getProducts()
et this.props.products
sont possibles grâce à mapStateToProps
et mapDispatchToProps
.
mapStateToProps
et mapDispatchToProps
State est le magasin Redux et Dispatch est les actions que nous lançons. Ces deux éléments seront exposés en tant qu'accessoires dans le composant.
function mapStateToProps(state) { return { products: state.products }; } function mapDispatchToProps(dispatch) { return { ProductAction: bindActionCreators(ProductAction, dispatch) }; } export default connect(mapStateToProps, mapDispatchToProps)(ProductsList);
modes
Dans React, les styles natifs sont généralement définis sur la même page. C'est similaire au CSS, mais nous utilisons des propriétés camelCase
au lieu de propriétés avec trait d'union.
const styles = StyleSheet.create({ list: { flexDirection: 'column' }, view: { padding: 10 }, loader: { width: 200, height: 200, alignItems: 'center', justifyContent: 'center', }, image: { width: 150, height: 150 }, text: { textAlign: 'center', fontSize: 20, padding: 5 } });
Page de produit unique
Cette page contient les détails d'un produit sélectionné. Il montre à l'utilisateur le nom, le prix et la description du produit. Il dispose également de la fonction "Ajouter au panier".
Page du panier
Cet écran affiche la liste des articles dans le panier. L'action a les fonctions getCart
, addToCart
et removeFromCart
. Le réducteur gère les actions de la même manière. L'identification des actions se fait par actionTypes - des constantes qui décrivent l'action qui sont stockées dans un fichier séparé.
export const GET_PRODUCTS_SUCCESS = 'GET_PRODUCTS_SUCCESS' export const GET_PRODUCTS_FAILED = 'GET_PRODUCTS_FAILED'; export const GET_CART_SUCCESS = 'GET_CART_SUCCESS'; export const ADD_TO_CART_SUCCESS = 'ADD_TO_CART_SUCCESS'; export const REMOVE_FROM_CART_SUCCESS = 'REMOVE_FROM_CART_SUCCESS';
Voici le code du composant CartPage
:
class CartPage extends React.Component { componentDidMount() { this.props.CartAction.getCart(); } _keyExtractor = (item, index) => item.id; removeItem(item) { this.props.CartAction.removeFromCart(item); } render() { const { cart } = this.props; console.log('render cart', cart) if (cart && cart.length > 0) { const Items = <FlatList contentContainerStyle={styles.list} data={cart} keyExtractor={this._keyExtractor} renderItem={({ item }) => <View style={styles.lineItem} > <Image style={styles.image} source={{ uri: item.image }} /> <Text style={styles.text}>{item.name}</Text> <Text style={styles.text}>{item.quantity}</Text> <TouchableOpacity style={{ marginLeft: 'auto' }} onPress={() => this.removeItem(item)}><Entypo name="cross" size={30} /></TouchableOpacity> </View> } />; return ( <View style={styles.container}> {Items} </View> ) } else { return ( <View style={styles.container}> <Text>Cart is empty!</Text> </View> ) } } }
Comme vous pouvez le voir, nous utilisons une FlatList
pour parcourir les éléments du panier. Il prend un tableau et crée une liste d'éléments à afficher à l'écran.
Conclusion
Vous pouvez configurer des informations sur l'application telles que le nom et l'icône dans le fichier app.json
. L'application peut être publiée après l'installation de npm exp.
Pour résumer:
- Nous avons maintenant une application e-commerce décente avec React Native ;
- Expo peut être utilisé pour exécuter le projet sur un smartphone ;
- Les technologies backend existantes telles que WordPress peuvent être utilisées ;
- Redux peut être utilisé pour gérer l'état de l'ensemble de l'application ;
- Les développeurs Web, en particulier les développeurs React, peuvent tirer parti de ces connaissances pour créer des applications plus volumineuses.
Pour l'application complète, vous pouvez visiter mon projet sur Github et le cloner. N'hésitez pas à le bifurquer et à l'améliorer davantage. En tant qu'exercice, vous pouvez continuer à créer d'autres fonctionnalités dans le projet, telles que :
- Page de paiement,
- Authentification,
- Stockage des données du panier dans AsyncStorage afin que la fermeture de l'application n'efface pas le panier.