React Native 및 WordPress를 사용하여 모바일 앱 빌드

게시 됨: 2022-03-10
빠른 요약 ↬ WordPress는 특히 콘텐츠 기반 또는 온라인 상점인 경우 차세대 기본 앱을 위한 훌륭한 백엔드 플랫폼으로 작동할 수 있습니다. 이 기사에서는 React Native 및 WordPress를 사용하여 모바일 앱을 빌드하기 위한 기초를 배웁니다.

웹 개발자로서 모바일 앱 개발에는 다른 프로그래밍 언어에 대한 새로운 학습 곡선이 필요하다고 생각했을 것입니다. iOS와 Android 모두에서 제대로 작동하려면 Java와 Swift를 스킬 세트에 추가해야 할 수도 있습니다.

하지만 이 기사는 당신을 놀라게 합니다! WooCommerce 플랫폼을 백엔드로 사용하여 iOS 및 Android용 전자 상거래 애플리케이션을 구축하는 방법을 살펴보겠습니다. 이것은 네이티브 크로스 플랫폼 개발을 시작하려는 모든 사람에게 이상적인 출발점이 될 것입니다.

크로스 플랫폼 개발의 간략한 역사

2011년, 우리는 하이브리드 모바일 앱 개발의 시작을 봅니다. Apache Cordova, PhoneGap 및 Ionic Framework와 같은 프레임워크가 천천히 등장합니다. 모든 것이 좋아 보이고 웹 개발자는 기존 지식으로 모바일 앱을 열심히 코딩하고 있습니다.

그러나 모바일 앱은 여전히 ​​웹사이트의 모바일 버전처럼 보였습니다. Android의 머티리얼 디자인이나 iOS의 평평한 모양과 같은 기본 디자인이 없습니다. 탐색은 웹과 유사하게 작동했으며 전환이 매끄럽지 않았습니다. 사용자는 하이브리드 접근 방식을 사용하여 구축된 앱에 만족하지 않고 기본 경험을 꿈꿨습니다.

2015년 3월로 넘어가면 React Native가 등장합니다. 개발자는 많은 개발자가 선호하는 JavaScript 라이브러리인 React를 사용하여 진정한 네이티브 크로스 플랫폼 애플리케이션을 구축할 수 있습니다. 이제 그들은 JavaScript로 알고 있는 것 외에도 작은 라이브러리를 쉽게 배울 수 있습니다. 이 지식을 바탕으로 개발자는 이제 웹, iOS 및 Android를 대상으로 합니다.

점프 후 더! 아래에서 계속 읽기 ↓

또한 개발 중 코드에 대한 변경 사항이 테스트 장치에 거의 즉시 로드됩니다! 이전에는 다른 접근 방식을 통해 기본 개발을 수행할 때 몇 분이 걸렸습니다. 개발자는 이전에 웹 개발을 좋아했던 즉각적인 피드백을 즐길 수 있습니다.

React 개발자는 기존 패턴을 새로운 플랫폼에 완전히 사용할 수 있게 되어 매우 기쁩니다. 실제로 그들은 이미 잘 알고 있는 플랫폼을 두 개 더 목표로 삼고 있습니다.

이것은 모두 프론트 엔드 개발에 좋습니다. 그러나 백엔드 기술에 대해 우리는 어떤 선택을 할 수 있습니까? 우리는 여전히 새로운 언어나 프레임워크를 배워야 합니까?

워드프레스 REST API

2016년 말, WordPress는 대망의 REST API를 코어에 출시하고 백엔드가 분리된 솔루션의 문을 열었습니다.

따라서 이미 WordPress 및 WooCommerce 웹 사이트가 있고 웹 사이트와 기본 앱에서 정확히 동일한 제품 및 사용자 프로필을 유지하려는 경우 이 문서가 적합합니다!

이 기사의 가정

React Native를 사용하여 WooCommerce 스토어로 모바일 앱을 빌드하기 위해 WordPress 기술을 사용하는 방법을 안내해 드리겠습니다. 이 기사에서는 다음을 가정합니다.

  • 최소한 초보자 수준에서는 다양한 WordPress API에 익숙합니다.
  • React의 기본 사항에 익숙합니다.
  • WordPress 개발 서버가 준비되었습니다. Apache와 함께 Ubuntu를 사용합니다.
  • Expo로 테스트할 Android 또는 iOS 기기가 있습니다.

이 튜토리얼에서 구축할 내용

이 기사를 통해 구축할 프로젝트는 패션 스토어 앱입니다. 앱에는 다음과 같은 기능이 있습니다.

  • 모든 제품을 나열하는 쇼핑 페이지,
  • 선택한 항목의 세부 정보가 있는 단일 제품 페이지,
  • '장바구니에 담기' 기능,
  • '장바구니에 항목 표시' 기능,
  • '장바구니에서 항목 제거' 기능.

이 기사는 이 프로젝트를 React Native를 사용하여 복잡한 모바일 앱을 빌드하기 위한 시작점으로 사용하도록 영감을 주는 것을 목표로 합니다.

참고 : 전체 애플리케이션을 보려면 Github에서 내 프로젝트를 방문하여 복제할 수 있습니다.

프로젝트 시작하기

공식 React Native 문서에 따라 앱 빌드를 시작합니다. 개발 환경에 Node를 설치했으면 명령 프롬프트를 열고 다음 명령을 입력하여 Create React Native App을 전역으로 설치합니다.

 npm install -g create-react-native-app

다음으로 프로젝트를 생성할 수 있습니다.

 create-react-native-app react-native-woocommerce-store

이것은 Expo로 테스트할 수 있는 새로운 React Native 프로젝트를 생성할 것입니다.

다음으로 테스트하려는 모바일 장치에 Expo 앱을 설치해야 합니다. iOS와 Android 모두에서 사용할 수 있습니다.

Expo 앱을 설치하면 개발 머신에서 npm start를 실행할 수 있습니다.

 cd react-native-woocommerce-store npm start
Expo를 통해 명령줄을 통해 React Native 프로젝트를 시작합니다. (큰 미리보기)

그 후 Expo 앱을 통해 QR 코드를 스캔하거나 앱의 검색창에 주어진 URL을 입력할 수 있습니다. 모바일에서 기본 'Hello World' 앱을 실행합니다. 이제 App.js를 편집하여 전화에서 실행 중인 앱을 즉시 변경할 수 있습니다.

또는 에뮬레이터에서 앱을 실행할 수 있습니다. 그러나 간결함과 정확성을 위해 실제 장치에서 실행하는 방법을 다룰 것입니다.

다음으로 이 명령을 사용하여 앱에 필요한 모든 패키지를 설치해 보겠습니다.

 npm install -s axios react-native-htmlview react-navigation react-redux redux redux-thunk

WordPress 사이트 설정

이 기사는 React Native 앱을 만드는 것에 관한 것이므로 WordPress 사이트를 만드는 방법에 대한 자세한 내용은 다루지 않겠습니다. Ubuntu에 WordPress를 설치하는 방법은 이 문서를 참조하십시오. WooCommerce REST API는 HTTPS가 필요하므로 Let's Encrypt를 사용하여 설정했는지 확인하십시오. 방법 안내는 이 문서를 참조하십시오.

모바일 장치에서 앱을 실행하고 HTTPS가 필요하기 때문에 localhost에 WordPress 설치를 생성하지 않습니다.

WordPress와 HTTPS가 성공적으로 설정되면 사이트에 WooCommerce 플러그인을 설치할 수 있습니다.

WordPress 설치에 WooCommerce 플러그인 설치. (큰 미리보기)

플러그인을 설치하고 활성화한 후 마법사를 따라 WooCommerce 스토어 설정을 계속합니다. 마법사가 완료되면 '대시보드로 돌아가기'를 클릭합니다.

다른 프롬프트가 표시됩니다.

WooCommerce에 예제 제품 추가. (큰 미리보기)

'가자'를 클릭하여 '예제 제품 추가'를 클릭합니다. 이렇게 하면 앱에 표시할 자체 제품을 만드는 시간을 절약할 수 있습니다.

상수 파일

WooCommerce REST API에서 스토어 제품을 로드하려면 앱 내부에 관련 키가 필요합니다. 이를 위해 우리는 constans.js 파일을 가질 수 있습니다.

먼저 'src'라는 폴더를 만들고 내부에 다음과 같이 하위 폴더를 만듭니다.

constants 폴더 안에 'Constants.js' 파일을 생성합니다. (큰 미리보기)

이제 WooCommerce의 키를 생성해 보겠습니다. 워드프레스 대시보드에서 WooCommerce → 설정 → API → 키/앱으로 이동하여 '키 추가'를 클릭합니다.

다음으로 이름이 React Native인 읽기 전용 키를 만듭니다. 소비자 키와 소비자 비밀을 다음과 같이 constants.js 파일에 복사합니다.

 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;

React 탐색으로 시작하기

React Navigation은 다른 화면 사이를 탐색하기 위한 커뮤니티 솔루션이며 독립 실행형 라이브러리입니다. 개발자는 몇 줄의 코드로 React Native 앱의 화면을 설정할 수 있습니다.

React Navigation에는 다양한 탐색 방법이 있습니다.

  • 스택,
  • 스위치,
  • 탭,
  • 서랍,
  • 그리고 더.

애플리케이션의 경우 StackNavigationDrawerNavigation 의 조합을 사용하여 다른 화면 사이를 탐색합니다. StackNavigation 은 웹에서 브라우저 기록이 작동하는 방식과 유사합니다. 헤더 및 헤더 탐색 아이콘에 대한 인터페이스를 제공하기 때문에 이것을 사용하고 있습니다. 데이터 구조의 스택과 유사한 푸시 및 팝이 있습니다. 푸시는 탐색 스택의 맨 위에 새 화면을 추가한다는 의미입니다. Pop은 스택에서 화면을 제거합니다.

이 코드는 StackNavigation 에 실제로 DrawerNavigation 이 자체적으로 포함되어 있음을 보여줍니다. 또한 헤더 스타일 및 헤더 버튼에 대한 속성을 사용합니다. 탐색 창 버튼을 왼쪽에 배치하고 장바구니 버튼을 오른쪽에 배치합니다. 서랍 버튼은 서랍을 켜고 끄는 반면 장바구니 버튼은 사용자를 장바구니 화면으로 안내합니다.

 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 은 홈, 쇼핑 및 장바구니 사이를 탐색할 수 있는 측면 서랍을 제공합니다. DrawerNavigator 는 사용자가 방문할 수 있는 다양한 화면, 즉 홈 페이지, 제품 페이지, 제품 페이지 및 장바구니 페이지를 나열합니다. 또한 서랍 컨테이너를 가져오는 속성이 있습니다. 즉, 햄버거 메뉴를 클릭할 때 열리는 슬라이딩 메뉴입니다.

 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 }); 
#
왼쪽: 홈페이지( homepage.js ). 오른쪽: 열린 서랍(DrawerContainer.js).

Redux Store를 App.js에 주입하기

이 앱에서 Redux를 사용하기 때문에 스토어를 앱에 삽입해야 합니다. Provider 구성 요소의 도움으로 이 작업을 수행합니다.

 const store = configureStore(); class App extends React.Component { render() { return ( <Provider store={store}> <ConnectedApp /> </Provider> ) } }

그런 다음 헤더에 장바구니 수를 포함할 수 있도록 ConnectedApp 구성 요소를 갖게 됩니다.

 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);

Redux 스토어, 액션, 리듀서

Redux에는 세 가지 다른 부분이 있습니다.

  1. 가게
    전체 응용 프로그램의 전체 상태를 유지합니다. 상태를 변경하는 유일한 방법은 해당 상태로 작업을 전달하는 것입니다.
  2. 행위
    상태를 변경하려는 의도를 나타내는 일반 개체입니다.
  3. 감속기
    상태 및 작업 유형을 수락하고 새 상태를 반환하는 함수입니다.

Redux의 이 세 가지 구성 요소는 전체 앱에 대해 예측 가능한 상태를 달성하는 데 도움이 됩니다. 단순화를 위해 Redux 스토어에서 제품을 가져와 저장하는 방법을 살펴보겠습니다.

먼저 스토어 생성을 위한 코드를 살펴보겠습니다.

 let middleware = [thunk]; export default function configureStore() { return createStore( RootReducer, applyMiddleware(...middleware) ); }

다음으로 제품 작업은 원격 웹사이트에서 제품을 가져오는 역할을 합니다.

 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); }) }; }

제품 리듀서는 데이터의 페이로드와 수정이 필요한지 여부를 반환하는 역할을 합니다.

 export default function (state = InitialState.products, action) { switch (action.type) { case types.GET_PRODUCTS_SUCCESS: return action.products; default: return state; } }

WooCommerce Shop 표시

products.js 파일은 Shop 페이지입니다. 기본적으로 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()this.props.productsmapStateToPropsmapDispatchToProps 로 인해 가능합니다.

상품 목록 화면입니다. (큰 미리보기)

mapStateToPropsmapDispatchToProps

State는 Redux 저장소이고 Dispatch는 우리가 실행하는 작업입니다. 둘 다 구성 요소에서 소품으로 노출됩니다.

 function mapStateToProps(state) { return { products: state.products }; } function mapDispatchToProps(dispatch) { return { ProductAction: bindActionCreators(ProductAction, dispatch) }; } export default connect(mapStateToProps, mapDispatchToProps)(ProductsList);

스타일

React에서 Native 스타일은 일반적으로 같은 페이지에 정의됩니다. CSS와 유사하지만 하이픈으로 연결된 속성 대신 camelCase 속성을 사용합니다.

 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 } });

단일 제품 페이지

이 페이지에는 선택한 제품의 세부 정보가 포함되어 있습니다. 그것은 사용자에게 제품의 이름, 가격 및 설명을 보여줍니다. '장바구니에 담기' 기능도 있습니다.

단일 제품 페이지입니다. (큰 미리보기)

장바구니 페이지

장바구니에 담긴 상품의 목록을 보여주는 화면입니다. 이 작업에는 getCart , addToCartremoveFromCart 기능이 있습니다. 감속기는 마찬가지로 작업을 처리합니다. 작업 식별은 actionTypes를 통해 수행됩니다. 즉, 별도의 파일에 저장된 작업을 설명하는 상수입니다.

 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';

다음은 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> ) } } }

보시다시피 FlatList 를 사용하여 장바구니 항목을 반복합니다. 배열을 받아 화면에 표시할 항목 목록을 만듭니다.

#
왼쪽: 항목이 있는 장바구니 페이지. 오른쪽: 장바구니 페이지가 비어 있을 때의 페이지입니다.

결론

app.json 파일에서 이름, 아이콘 등 앱에 대한 정보를 구성할 수 있습니다. npm이 exp를 설치한 후 앱을 게시할 수 있습니다.

요약하자면:

  • 이제 React Native로 괜찮은 전자 상거래 애플리케이션이 생겼습니다.
  • Expo는 스마트폰에서 프로젝트를 실행하는 데 사용할 수 있습니다.
  • WordPress와 같은 기존 백엔드 기술을 사용할 수 있습니다.
  • Redux는 전체 앱의 상태를 관리하는 데 사용할 수 있습니다.
  • 웹 개발자, 특히 React 개발자는 이 지식을 활용하여 더 큰 앱을 빌드할 수 있습니다.

전체 애플리케이션의 경우 Github에서 내 프로젝트를 방문하여 복제할 수 있습니다. 자유롭게 포크하고 더 개선하십시오. 연습으로 다음과 같은 더 많은 기능을 프로젝트에 계속 구축할 수 있습니다.

  • 결제 페이지,
  • 입증,
  • 앱을 닫아도 장바구니가 지워지지 않도록 장바구니 데이터를 AsyncStorage에 저장합니다.