Tworzenie aplikacji mobilnych za pomocą React Native i WordPress
Opublikowany: 2022-03-10Jako programiści stron internetowych możesz pomyśleć, że tworzenie aplikacji mobilnych wymaga świeżej krzywej uczenia się z innym językiem programowania. Być może Java i Swift muszą zostać dodane do twojego zestawu umiejętności, aby zacząć działać zarówno z iOS, jak i Androidem, a to może Cię zniechęcić.
Ale w tym artykule czeka Cię niespodzianka! Przyjrzymy się zbudowaniu aplikacji e-commerce na iOS i Androida z wykorzystaniem platformy WooCommerce jako naszego backendu. Byłby to idealny punkt wyjścia dla każdego, kto chce rozpocząć natywny rozwój międzyplatformowy.
Krótka historia rozwoju międzyplatformowego
Jest rok 2011 i widzimy początek tworzenia hybrydowych aplikacji mobilnych. Powoli pojawiają się frameworki takie jak Apache Cordova, PhoneGap i Ionic Framework. Wszystko wygląda dobrze, a twórcy stron internetowych chętnie kodują aplikacje mobilne, korzystając ze swojej dotychczasowej wiedzy.
Jednak aplikacje mobilne nadal wyglądały jak mobilne wersje stron internetowych. Brak natywnych projektów, takich jak Material Design Androida lub płaski wygląd iOS. Nawigacja działała podobnie do sieci, a przejścia nie były płynne. Użytkownicy nie byli zadowoleni z aplikacji zbudowanych w podejściu hybrydowym i marzyli o natywnym doświadczeniu.
Przewiń do marca 2015 r. i na scenie pojawia się React Native. Programiści mogą tworzyć prawdziwie natywne aplikacje wieloplatformowe za pomocą React, ulubionej biblioteki JavaScript dla wielu programistów. Są teraz w stanie łatwo nauczyć się małej biblioteki, oprócz tego, co znają dzięki JavaScript. Mając tę wiedzę, programiści są teraz ukierunkowani na Internet, iOS i Androida.
Co więcej, zmiany wprowadzone w kodzie podczas projektowania są ładowane na urządzenia testowe niemal natychmiast! Zajmowało to kilka minut, gdy programowaliśmy natywnie za pomocą innych podejść. Deweloperzy mogą cieszyć się natychmiastową informacją zwrotną, którą uwielbiali podczas tworzenia stron internetowych.
Deweloperzy Reacta są bardziej niż szczęśliwi, że mogą wykorzystać istniejące wzorce, które zastosowali, na zupełnie nowej platformie. W rzeczywistości celują w dwie kolejne platformy z tym, co już bardzo dobrze znają.
To wszystko jest dobre dla rozwoju front-endu. Ale jaki mamy wybór dla technologii back-endu? Czy nadal musimy uczyć się nowego języka lub frameworka?
Interfejs API REST WordPress
Pod koniec 2016 r. WordPress udostępnił bardzo oczekiwany REST API do rdzenia i otworzył drzwi dla rozwiązań z oddzielonymi backendami.
Jeśli więc masz już witrynę WordPress i WooCommerce i chcesz zachować dokładnie te same oferty i profile użytkowników w swojej witrynie i natywnej aplikacji, ten artykuł jest dla Ciebie!
Założenia dokonane w tym artykule
Przeprowadzę Cię przez proces wykorzystania Twoich umiejętności WordPress do zbudowania aplikacji mobilnej ze sklepem WooCommerce przy użyciu React Native. Artykuł zakłada:
- Znasz różne interfejsy API WordPress, przynajmniej na poziomie początkującym.
- Znasz podstawy Reacta.
- Masz gotowy serwer programistyczny WordPress. Używam Ubuntu z Apache.
- Masz urządzenie z Androidem lub iOS do przetestowania z Expo.
Co zbudujemy w tym samouczku
Projekt, który zamierzamy zbudować na podstawie tego artykułu, to aplikacja sklepu z modą. Aplikacja będzie posiadała następujące funkcjonalności:
- Strona sklepu zawierająca wszystkie produkty,
- Strona pojedynczego produktu ze szczegółami wybranej pozycji,
- funkcja „Dodaj do koszyka”,
- funkcja „Pokaż przedmioty w koszyku”,
- Funkcja „Usuń przedmiot z koszyka”.
Ten artykuł ma na celu zainspirowanie Cię do wykorzystania tego projektu jako punktu wyjścia do budowania złożonych aplikacji mobilnych przy użyciu React Native.
Uwaga : Aby uzyskać pełną aplikację, możesz odwiedzić mój projekt na Github i sklonować go .
Rozpoczęcie pracy z naszym projektem
Zaczniemy budować aplikację zgodnie z oficjalną dokumentacją React Native. Po zainstalowaniu Node w środowisku programistycznym otwórz wiersz polecenia i wpisz następujące polecenie, aby globalnie zainstalować aplikację Create React Native.
npm install -g create-react-native-app
Następnie możemy stworzyć nasz projekt
create-react-native-app react-native-woocommerce-store
Stworzy to nowy projekt React Native, który możemy przetestować za pomocą Expo.
Następnie musimy zainstalować aplikację Expo na naszym urządzeniu mobilnym, które chcemy przetestować. Jest dostępny zarówno na iOS, jak i Androida.
Po zainstalowaniu aplikacji Expo możemy uruchomić npm start na naszej maszynie deweloperskiej.
cd react-native-woocommerce-store npm start
Następnie możesz zeskanować kod QR za pomocą aplikacji Expo lub wpisać podany adres URL w pasku wyszukiwania aplikacji. Spowoduje to uruchomienie podstawowej aplikacji „Hello World” w telefonie komórkowym. Możemy teraz edytować App.js, aby wprowadzać natychmiastowe zmiany w aplikacji działającej na telefonie.
Alternatywnie możesz uruchomić aplikację na emulatorze. Ale dla zwięzłości i dokładności omówimy uruchomienie go na rzeczywistym urządzeniu.
Następnie zainstalujmy wszystkie wymagane pakiety aplikacji za pomocą tego polecenia:
npm install -s axios react-native-htmlview react-navigation react-redux redux redux-thunk
Konfigurowanie witryny WordPress
Ponieważ ten artykuł dotyczy tworzenia aplikacji React Native, nie będziemy wchodzić w szczegóły tworzenia witryny WordPress. Zapoznaj się z tym artykułem, jak zainstalować WordPress na Ubuntu. Ponieważ WooCommerce REST API wymaga protokołu HTTPS, upewnij się, że jest skonfigurowany za pomocą Let's Encrypt. Zapoznaj się z tym artykułem, aby uzyskać przewodnik.
Nie tworzymy instalacji WordPressa na localhoście, ponieważ będziemy uruchamiać aplikację na urządzeniu mobilnym, a także ponieważ potrzebny jest HTTPS.
Po pomyślnym skonfigurowaniu WordPress i HTTPS możemy zainstalować wtyczkę WooCommerce na stronie.
Po zainstalowaniu i aktywacji wtyczki kontynuuj konfigurację sklepu WooCommerce, postępując zgodnie z kreatorem. Po zakończeniu działania kreatora kliknij „Powrót do pulpitu nawigacyjnego”.
Zostaniesz przywitany przez kolejny monit.
Kliknij „Chodźmy” do „Dodaj przykładowe produkty”. Dzięki temu zaoszczędzimy czas na tworzenie własnych produktów do wyświetlenia w aplikacji.
Plik stałych
Aby załadować produkty naszego sklepu z WooCommerce REST API, potrzebujemy odpowiednich kluczy w naszej aplikacji. W tym celu możemy mieć plik constans.js
.
Najpierw utwórz folder o nazwie „src” i utwórz podfoldery wewnątrz w następujący sposób:
Teraz wygenerujmy klucze dla WooCommerce. W panelu WordPress przejdź do WooCommerce → Ustawienia → API → Klucze/Aplikacje i kliknij „Dodaj klucz”.
Następnie utwórz klucz tylko do odczytu o nazwie React Native. Skopiuj klucz klienta i tajny klucz klienta do pliku constants.js
w następujący sposób:
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;
Zaczynając od nawigacji React
React Navigation to rozwiązanie społecznościowe do poruszania się między różnymi ekranami i samodzielna biblioteka. Pozwala programistom skonfigurować ekrany aplikacji React Native za pomocą zaledwie kilku linijek kodu.
W React Navigation dostępne są różne metody nawigacji:
- Stos,
- Przełącznik,
- Zakładki,
- Szuflada,
- i więcej.
W naszej aplikacji użyjemy kombinacji StackNavigation
i DrawerNavigation
do poruszania się między różnymi ekranami. StackNavigation
działa podobnie do historii przeglądarki w sieci. Używamy tego, ponieważ zapewnia interfejs dla nagłówka i ikon nawigacji nagłówka. Ma push i pop podobne do stosów w strukturach danych. Push oznacza, że dodajemy nowy ekran na górze stosu nawigacyjnego. Pop usuwa ekran ze stosu.
Kod pokazuje, że StackNavigation
w rzeczywistości zawiera w sobie DrawerNavigation
. Pobiera również właściwości stylu nagłówka i przycisków nagłówka. Przycisk szuflady nawigacji umieszczamy po lewej stronie, a po prawej przycisk koszyka zakupów. Przycisk szuflady włącza i wyłącza szufladę, natomiast przycisk koszyka przenosi użytkownika na ekran koszyka.
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> );
Z drugiej strony DrawerNavigation
zapewnia boczną szufladę, która pozwoli nam nawigować między domem, sklepem i koszykiem. DrawerNavigator
wyświetla listę różnych ekranów, które użytkownik może odwiedzić, a mianowicie stronę główną, stronę produktów, stronę produktu i stronę koszyka. Posiada również właściwość, która zabierze kontener szuflady: przesuwane menu, które otwiera się po kliknięciu menu hamburgera.
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 });
Wstrzykiwanie sklepu Redux do App.js
Ponieważ używamy Redux w tej aplikacji, musimy wstrzyknąć sklep do naszej aplikacji. Robimy to za pomocą komponentu Provider
.
const store = configureStore(); class App extends React.Component { render() { return ( <Provider store={store}> <ConnectedApp /> </Provider> ) } }
Będziemy mieli wtedy komponent ConnectedApp
, dzięki czemu będziemy mogli wyświetlić liczbę koszyków w nagłówku.
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);
Sklep Redux, akcje i reduktory
W Redux mamy trzy różne części:
- Sklep
Przechowuje cały stan całej aplikacji. Jedynym sposobem na zmianę stanu jest wysłanie do niego akcji. - działania
Zwykły obiekt, który reprezentuje zamiar zmiany stanu. - Reduktory
Funkcja, która akceptuje stan i typ akcji oraz zwraca nowy stan.
Te trzy składniki Redux pomagają nam osiągnąć przewidywalny stan całej aplikacji. Dla uproszczenia przyjrzymy się, jak produkty są pobierane i zapisywane w sklepie Redux.
Przede wszystkim spójrzmy na kod do stworzenia sklepu:
let middleware = [thunk]; export default function configureStore() { return createStore( RootReducer, applyMiddleware(...middleware) ); }
Następnie akcja products odpowiada za pobranie produktów ze zdalnej strony internetowej.
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); }) }; }
Reduktor produktów jest odpowiedzialny za zwrócenie ładunku danych i to, czy wymaga ono modyfikacji.
export default function (state = InitialState.products, action) { switch (action.type) { case types.GET_PRODUCTS_SUCCESS: return action.products; default: return state; } }
Wyświetlanie sklepu WooCommerce
Plik products.js
to nasza strona Sklepu. Zasadniczo wyświetla listę produktów z 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
są możliwe dzięki mapStateToProps
i mapDispatchToProps
.
mapStateToProps
i mapDispatchToProps
State to sklep Redux, a Dispatch to akcje, które uruchamiamy. Oba te elementy będą widoczne jako rekwizyty w komponencie.
function mapStateToProps(state) { return { products: state.products }; } function mapDispatchToProps(dispatch) { return { ProductAction: bindActionCreators(ProductAction, dispatch) }; } export default connect(mapStateToProps, mapDispatchToProps)(ProductsList);
Style
W React, style natywne są generalnie definiowane na tej samej stronie. Jest podobny do CSS, ale używamy właściwości camelCase
zamiast właściwości z łącznikami.
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 } });
Pojedyncza strona produktu
Ta strona zawiera szczegóły wybranego produktu. Pokazuje użytkownikowi nazwę, cenę i opis produktu. Posiada również funkcję „Dodaj do koszyka”.
Strona koszyka
Ten ekran pokazuje listę pozycji w koszyku. Akcja posiada funkcje getCart
, addToCart
i removeFromCart
. Reduktor również obsługuje te akcje. Identyfikacja akcji odbywa się za pomocą actionTypes — stałych opisujących akcje, które są przechowywane w osobnym pliku.
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';
To jest kod komponentu 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> ) } } }
Jak widać, używamy FlatList
do iteracji elementów koszyka. Pobiera tablicę i tworzy listę elementów do wyświetlenia na ekranie.
Wniosek
Możesz skonfigurować informacje o aplikacji, takie jak nazwa i ikona w pliku app.json
. Aplikację można opublikować po zainstalowaniu npm exp.
Podsumowując:
- Mamy teraz przyzwoitą aplikację e-commerce z React Native;
- Expo można wykorzystać do uruchomienia projektu na smartfonie;
- Można wykorzystać istniejące technologie backendowe, takie jak WordPress;
- Redux może być używany do zarządzania stanem całej aplikacji;
- Twórcy stron internetowych, zwłaszcza programiści React, mogą wykorzystać tę wiedzę do tworzenia większych aplikacji.
Aby uzyskać pełną aplikację, możesz odwiedzić mój projekt na Github i sklonować go. Możesz go rozwidlić i dalej ulepszać. W ramach ćwiczenia możesz kontynuować budowanie większej liczby funkcji w projekcie, takich jak:
- Strona kasy,
- Uwierzytelnianie,
- Przechowywanie danych koszyka w AsyncStorage, aby zamknięcie aplikacji nie spowodowało wyczyszczenia koszyka.