Shop App 001
1 계획
1) product overview screen : image, title, cart, detail button
2) cart detail screen
3) product detail screen
4) Navigation : shop, orders, manage products
- orders
- mange products : plus button → edit product screen
2 생성, Setup
Create
$ expo init wordmall
Setup
$ npm install --save react-native react-native-screens
$ npm install --save redux react-redux react-navigation react-navigation-header-buttons
$ npm install --save react-navigation-stack @react-native-community/masked-view react-native-safe-area-context
$ npm install --save react-native-gesture-handler react-native-reanimated
리덕스, 네비게이션을 사용하는 앱을 만들 것입니다.
Initial state & Dummy data
models/product.js
class Product {
constructor(id, ownerId, title, imageUrl, description, price) {
this.id = id;
this.ownerId = ownerId;
this.imageUrl = imageUrl;
this.title = title;
this.description = description;
this.price = price;
}
}
data/dummy-data.js
import Product from '../models/product';
const PRODUCTS = [
new Product(
'p1',
'u1',
'Red Shirt',
'https://cdn.pixabay.com/photo/2016/10/02/22/17/red-t-shirt-1710578_1280.jpg',
'A red t-shirt, perfect for days with non-red weather.',
29.99
),
...
];
export default PRODUCTS;
ProductOverviewScreen
은 우리의 메인 화면입니다.
이 곳에 띄우게 될 기본 데이터 모델을 만들고, 데이터를 만들어봅니다.
Redux Setting
여러 컴포넌트를 효율적으로 관리할 수 있도록 리덕스 구조를 사용합니다.
store/actions/products
생성
store/reducers/products
import PRODUCTS from '../../data/dummy-data';
const initialState = {
availableProducts: PRODUCTS,
userProducts: PRODUCTS.filter((prod) => prod.ownerId === 'u1')
};
export default (state = initialState, action) => {
return state;
};
App.js
import React from 'react';
import { Text, View } from 'react-native';
import { createStore, combineReducers } from 'redux';
import { Provider } from 'react-redux';
import productsReducer from './store/reducers/products';
const rootReducer = combineReducers({
products: productsReducer
});
const store = createStore(rootReducer);
export default function App() {
return (
<Provider store={store}>
<View>...</View>
</Provider>
);
}
루트리듀서를 만들고, products 라는 키에 만들었던 productsReducer
를 등록합니다.
리듀서로 state 불러오기
screens/shop/ProductsOverviewScreen
import React from 'react';
import { FlatList, Text } from 'react-native';
import { useSelector } from 'react-redux';
const ProductsOverviewScreen = (props) => {
const products = useSelector((state) => state.products.availableProducts);
return (
<FlatList
data={products}
keyExtractor={(item) => item.id}
renderItem={(itemData) => <Text>{itemData.item.title}</Text>}
/>
);
};
ProductsOverviewScreen.navigationOptions = {
headerTitle: 'All Products'
};
export default ProductsOverviewScreen;
useSelector
를 통해 프로젝트에서 전역적으로 루트리듀서에 등록된 products
리듀서를 사용할 수 있습니다.
초깃값은 앞에서 다 설정해놓았고, const products = useSelector((state) => state.products.availableProducts);
이렇게 필요한 값을 끌어다가 사용할 수 있습니다.
FlatList
에 데이터를 넣고, 키 값을 id로 정해줍니다. 이 값은 꼭 필요하며, FlatList
의 성능을 높여주기 위함입니다. 아이템을 렌더링하기 위해 renderItem
에 위와 같은 방식으로 <Text>
컴포넌트에 아이템의 제목을 받아 리턴할 수 있습니다.
3 Navigator Setup
네비게이터 생성
navigation/ShopNavigator.js
import { createAppContainer } from 'react-navigation';
import { createStackNavigator } from 'react-navigation-stack';
import { Platform } from 'react-native';
import ProductsOverviewScreen from '../screens/shop/ProductOverviewScreen';
import Colors from '../constants/Colors';
const ProductsNavigator = createStackNavigator(
{
ProductsOverview: ProductsOverviewScreen
},
{
defaultNavigationOptions: {
headerStyle: {
backgroundColor: Platform.OS === 'android' ? Colors.primary : ''
},
headerTintColor: Platform.OS === 'android' ? 'white' : Colors.primary
}
}
);
export default createAppContainer(ProductsNavigator);
스택 네비게이터를 구성합니다. ProductsOverviewScreen
을 메인화면으로 보여줍니다.
네비게이션 기본값은, 플랫폼(Android, iOS)에 따라 headerStyle
의 배경색상과, headerTintColor
를 다르게 적용해줍니다.
마지막으로, createAppContainer
에 담아서 스택 네비게이터를 내보냅니다.
constants/Colors.js
export default {
primary: '#C2185B',
accent: '#FFC107'
};
자주 사용할 색상을 설정합니다.
네비게이터 등록
App.js 에 네비게이터를 등록해줍시다.
App.js
import React from 'react';
import { createStore, combineReducers } from 'redux';
import { Provider } from 'react-redux';
import productsReducer from './store/reducers/products';
import ShopNavigator from './navigation/ShopNavigator';
const rootReducer = combineReducers({
products: productsReducer
});
const store = createStore(rootReducer);
export default function App() {
return (
<Provider store={store}>
<ShopNavigator />
</Provider>
);
}
Expo 앱을 통해, 만든 환경을 띄워보려고 했는데 라이브러리 의존성 에러가 났다.
부족한 라이브러리를 설치해주니, 잘 작동한다.
$ expo install react-native-screens react-native-reanimated react-native-safe-area-context @react-native-community/masked-view
'App > React Native' 카테고리의 다른 글
[React Native] Touchable Component (281) | 2020.07.05 |
---|---|
[React Native] redux, navigation 세팅 (270) | 2020.07.05 |
[React Native] Expo 없이 앱 build하기 (325) | 2020.06.11 |
[React Native] 5 React Navigation 설정 (393) | 2020.05.16 |
[React Native] 4 반응형, 적응형 사용자 인터페이스 만들기 (281) | 2020.05.10 |
댓글