Crearea de aplicații mobile folosind React Native și WordPress
Publicat: 2022-03-10În calitate de dezvoltatori web, este posibil să fi crezut că dezvoltarea de aplicații mobile necesită o curbă nouă de învățare cu un alt limbaj de programare. Poate că Java și Swift trebuie adăugate la setul dvs. de abilități pentru a începe funcționarea atât cu iOS, cât și cu Android, iar asta s-ar putea să vă blocheze.
Dar acest articol vă oferă o surpriză! Ne vom uita la construirea unei aplicații de comerț electronic pentru iOS și Android folosind platforma WooCommerce ca backend. Acesta ar fi un punct de plecare ideal pentru oricine dorește să intre în dezvoltarea nativă multiplatformă.
O scurtă istorie a dezvoltării multiplatforme
Este 2011 și vedem începutul dezvoltării aplicațiilor mobile hibride. Framework-uri precum Apache Cordova, PhoneGap și Ionic Framework apar încet. Totul arată bine, iar dezvoltatorii web codifică cu nerăbdare aplicațiile mobile cu cunoștințele lor existente.
Cu toate acestea, aplicațiile mobile încă arătau ca versiuni mobile ale site-urilor web. Fără modele native precum designul material al Android sau aspectul plat al iOS. Navigarea a funcționat similar cu web și tranzițiile nu au fost foarte fluide. Utilizatorii nu erau mulțumiți de aplicațiile create folosind abordarea hibridă și visau la experiența nativă.
Avanză rapid până în martie 2015, iar React Native apare pe scenă. Dezvoltatorii pot construi aplicații multiplatforme cu adevărat native folosind React, o bibliotecă JavaScript favorită pentru mulți dezvoltatori. Acum sunt capabili să învețe cu ușurință o mică bibliotecă pe lângă ceea ce știu cu JavaScript. Cu aceste cunoștințe, dezvoltatorii vizează acum web, iOS și Android.
În plus, modificările aduse codului în timpul dezvoltării sunt încărcate pe dispozitivele de testare aproape instantaneu! Acest lucru obișnuia să dureze câteva minute când aveam o dezvoltare nativă prin alte abordări. Dezvoltatorii se pot bucura de feedback-ul instantaneu pe care îi plăcea înainte cu dezvoltarea web.
Dezvoltatorii React sunt mai mult decât fericiți să poată folosi modelele existente pe care le-au urmat într-o nouă platformă. De fapt, ei vizează încă două platforme cu ceea ce cunosc deja foarte bine.
Toate acestea sunt bune pentru dezvoltarea front-end. Dar ce alegeri avem pentru tehnologia back-end? Mai trebuie să învățăm o limbă sau un cadru nou?
API-ul REST WordPress
La sfârșitul anului 2016, WordPress a lansat mult așteptatul REST API în nucleul său și a deschis porțile pentru soluții cu backend-uri decuplate.
Deci, dacă aveți deja un site web WordPress și WooCommerce și doriți să păstrați exact aceleași oferte și profiluri de utilizator pe site-ul dvs. web și aplicația nativă, acest articol este pentru dvs.!
Ipotezele formulate în acest articol
Vă voi ghida prin utilizarea abilităților dvs. WordPress pentru a crea o aplicație mobilă cu un magazin WooCommerce folosind React Native. Articolul presupune:
- Sunteți familiarizat cu diferitele API-uri WordPress, cel puțin la nivel de începător.
- Sunteți familiarizat cu elementele de bază ale React.
- Aveți un server de dezvoltare WordPress gata. Eu folosesc Ubuntu cu Apache.
- Aveți un dispozitiv Android sau iOS de testat cu Expo.
Ce vom construi în acest tutorial
Proiectul pe care îl vom construi prin acest articol este o aplicație pentru magazinul de modă. Aplicația va avea următoarele funcționalități:
- Pagina de magazin care listează toate produsele,
- Pagina de produs unică cu detalii ale articolului selectat,
- Funcția „Adaugă în coș”,
- Funcția „Afișați articolele în coș”,
- Funcția „Eliminați articolul din coș”.
Acest articol își propune să vă inspire să utilizați acest proiect ca punct de plecare pentru a construi aplicații mobile complexe folosind React Native.
Notă : Pentru aplicația completă, puteți vizita proiectul meu pe Github și îl puteți clona .
Începeți cu proiectul nostru
Vom începe să construim aplicația conform documentației oficiale React Native. După ce ați instalat Node în mediul dvs. de dezvoltare, deschideți promptul de comandă și tastați următoarea comandă pentru a instala aplicația Create React Native la nivel global.
npm install -g create-react-native-app
În continuare, ne putem crea proiectul
create-react-native-app react-native-woocommerce-store
Acest lucru va crea un nou proiect React Native pe care îl putem testa cu Expo.
În continuare, va trebui să instalăm aplicația Expo pe dispozitivul nostru mobil pe care dorim să-l testăm. Este disponibil atât pentru iOS, cât și pentru Android.
După ce am instalat aplicația Expo, putem rula npm start pe mașina noastră de dezvoltare.
cd react-native-woocommerce-store npm start
După aceea, puteți scana codul QR prin aplicația Expo sau puteți introduce adresa URL dată în bara de căutare a aplicației. Aceasta va rula aplicația de bază „Hello World” pe mobil. Acum putem edita App.js pentru a face modificări instantanee în aplicația care rulează pe telefon.
Alternativ, puteți rula aplicația pe un emulator. Dar pentru concizie și acuratețe, vom acoperi rularea acestuia pe un dispozitiv real.
Apoi, să instalăm toate pachetele necesare pentru aplicație folosind această comandă:
npm install -s axios react-native-htmlview react-navigation react-redux redux redux-thunk
Configurarea unui site WordPress
Deoarece acest articol este despre crearea unei aplicații React Native, nu vom intra în detalii despre crearea unui site WordPress. Vă rugăm să consultați acest articol despre cum să instalați WordPress pe Ubuntu. Deoarece WooCommerce REST API necesită HTTPS, vă rugăm să vă asigurați că este configurat folosind Let's Encrypt. Consultați acest articol pentru un ghid de utilizare.
Nu creăm o instalare WordPress pe localhost, deoarece vom rula aplicația pe un dispozitiv mobil și, de asemenea, deoarece este necesar HTTPS.
Odată ce WordPress și HTTPS sunt configurate cu succes, putem instala pluginul WooCommerce pe site.
După instalarea și activarea pluginului, continuați cu configurarea magazinului WooCommerce urmând expertul. După finalizarea expertului, faceți clic pe „Revenire la tabloul de bord”.
Veți fi întâmpinat de o altă solicitare.
Faceți clic pe „Să mergem” la „Adăugați exemple de produse”. Acest lucru ne va economisi timp pentru a ne crea propriile produse pentru a le afișa în aplicație.
Fișierul constantelor
Pentru a încărca produsele magazinului nostru din API-ul WooCommerce REST, avem nevoie de cheile relevante în aplicația noastră. În acest scop, putem avea un fișier constans.js
.
Mai întâi creați un folder numit „src” și creați subfoldere în interior, după cum urmează:
Acum, să generăm cheile pentru WooCommerce. În tabloul de bord WordPress, navigați la WooCommerce → Setări → API → Chei/Aplicații și faceți clic pe „Adăugați cheie”.
Apoi creați o cheie Numai citire cu numele React Native. Copiați cheia consumatorului și secretul consumatorului în fișierul constants.js
, după cum urmează:
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;
Începând cu React Navigation
React Navigation este o soluție comunitară pentru navigarea între diferitele ecrane și este o bibliotecă autonomă. Le permite dezvoltatorilor să configureze ecranele aplicației React Native cu doar câteva linii de cod.
Există diferite metode de navigare în React Navigation:
- Grămadă,
- Intrerupator,
- file,
- Sertar,
- și altele.
Pentru aplicația noastră vom folosi o combinație de StackNavigation
și DrawerNavigation
pentru a naviga între diferitele ecrane. StackNavigation
este similar cu modul în care funcționează istoricul browserului pe web. Utilizăm acest lucru deoarece oferă o interfață pentru antet și pictogramele de navigare din antet. Are push și pop similar cu stivele din structurile de date. Push înseamnă că adăugăm un nou ecran în partea de sus a Stivei de navigare. Pop elimină un ecran din stivă.
Codul arată că StackNavigation
, de fapt, găzduiește DrawerNavigation
în sine. De asemenea, necesită proprietăți pentru stilul antetului și butoanele antetului. Așezăm butonul sertarului de navigare în stânga și butonul coșului de cumpărături în dreapta. Butonul sertarului pornește și oprește sertarul, în timp ce butonul coș duce utilizatorul la ecranul coșului de cumpărături.
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> );
Pe de altă parte, DrawerNavigation
oferă sertarul lateral care ne va permite să navigăm între Acasă, Magazin și Coș. DrawerNavigator
listează diferitele ecrane pe care utilizatorul le poate vizita, și anume Pagina de pornire, Pagina Produse, Pagina Produs și Pagina Coș. De asemenea, are o proprietate care va prelua containerul Drawer: meniul glisant care se deschide când faceți clic pe meniul 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 });
Injectarea magazinului Redux în App.js
Deoarece folosim Redux în această aplicație, trebuie să injectăm magazinul în aplicația noastră. Facem acest lucru cu ajutorul componentei Provider
.
const store = configureStore(); class App extends React.Component { render() { return ( <Provider store={store}> <ConnectedApp /> </Provider> ) } }
Vom avea apoi o componentă ConnectedApp
, astfel încât să putem avea numărătoarea coșului în antet.
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);
Magazin Redux, acțiuni și reductoare
În Redux, avem trei părți diferite:
- Magazin
Deține întreaga stare a întregii aplicații. Singura modalitate de a schimba starea este să îi trimiți o acțiune. - Acțiuni
Un obiect simplu care reprezintă o intenție de a schimba starea. - Reductoare
O funcție care acceptă o stare și un tip de acțiune și returnează o stare nouă.
Aceste trei componente ale Redux ne ajută să obținem o stare previzibilă pentru întreaga aplicație. Pentru simplitate, ne vom uita la modul în care produsele sunt preluate și salvate în magazinul Redux.
În primul rând, să ne uităm la codul pentru crearea magazinului:
let middleware = [thunk]; export default function configureStore() { return createStore( RootReducer, applyMiddleware(...middleware) ); }
În continuare, acțiunea produselor este responsabilă pentru preluarea produselor de pe site-ul web la distanță.
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); }) }; }
Reductorul de produse este responsabil pentru returnarea încărcăturii utile de date și dacă trebuie modificată.
export default function (state = InitialState.products, action) { switch (action.type) { case types.GET_PRODUCTS_SUCCESS: return action.products; default: return state; } }
Se afișează magazinul WooCommerce
Fișierul products.js
este pagina noastră Magazin. Practic afișează lista de produse de la 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()
și this.props.products
sunt posibile datorită mapStateToProps
și mapDispatchToProps
.
mapStateToProps
și mapDispatchToProps
State este magazinul Redux și Dispatch sunt acțiunile pe care le declanșăm. Ambele vor fi expuse ca recuzită în componentă.
function mapStateToProps(state) { return { products: state.products }; } function mapDispatchToProps(dispatch) { return { ProductAction: bindActionCreators(ProductAction, dispatch) }; } export default connect(mapStateToProps, mapDispatchToProps)(ProductsList);
Stiluri
În React, stilurile native sunt, în general, definite pe aceeași pagină. Este similar cu CSS, dar folosim proprietăți camelCase
în loc de proprietăți cu silabe.
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 } });
Pagina cu un singur produs
Această pagină conține detalii despre un produs selectat. Acesta arată utilizatorului numele, prețul și descrierea produsului. Are și funcția „Adaugă în coș”.
Pagina de coș
Acest ecran arată lista de articole din coș. Acțiunea are funcțiile getCart
, addToCart
și removeFromCart
. Reductorul gestionează acțiunile la fel. Identificarea acțiunilor se face prin actionTypes — constante care descriu acțiunea care sunt stocate într-un fișier separat.
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';
Acesta este codul pentru componenta 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> ) } } }
După cum puteți vedea, folosim FlatList
pentru a itera articolele din coș. Acesta preia o matrice și creează o listă de elemente care urmează să fie afișate pe ecran.
Concluzie
Puteți configura informații despre aplicație, cum ar fi numele și pictograma în fișierul app.json
. Aplicația poate fi publicată după instalarea npm exp.
În concluzie:
- Acum avem o aplicație decentă de comerț electronic cu React Native;
- Expo poate fi folosit pentru a rula proiectul pe un smartphone;
- Tehnologiile backend existente, cum ar fi WordPress, pot fi utilizate;
- Redux poate fi folosit pentru a gestiona starea întregii aplicații;
- Dezvoltatorii web, în special dezvoltatorii React, pot folosi aceste cunoștințe pentru a crea aplicații mai mari.
Pentru aplicația completă, puteți vizita proiectul meu pe Github și îl puteți clona. Simțiți-vă liber să-l bifurcați și să îl îmbunătățiți în continuare. Ca exercițiu, puteți continua să construiți mai multe caracteristici în proiect, cum ar fi:
- Pagina de checkout,
- Autentificare,
- Stocarea datelor coșului în AsyncStorage, astfel încât închiderea aplicației să nu golească coșul.