⒈初始化 React Native環境
參考https://reactnative.cn/docs/getting-started.html
⒉安裝React Native官方的腳手架工具
npm install -g @react-native-community/cli
⒊使用React Native腳手架初始化項目
#默認是JavaScript npx react-native init ts_react_native #可以直接使用TypeScript初始化 npx react-native init ts_react_native --template react-native-template-typescript
⒋安裝watchman
watchman用於監控React Native項目中文件的變動,經常有開發者忘記安裝watchman而導致項目無法啟動的情況
cd ts_react_native
y watchman
⒌更改項目為TypeScript環境
1.將TypeScript以及React Native和Jest的類型添加到您的項目中。
yarn add typescript @types/jest @types/react @types/react-native @types/react-test-renderer # or for npm npm install --save-dev @types/jest @types/react @types/react-native @types/react-test-renderer
⒉在項目的根目錄中創建TypeScript配置文件tsconfig.json:
{ "compilerOptions": { "allowJs": true, "allowSyntheticDefaultImports": true, "esModuleInterop": true, "isolatedModules": true, "jsx": "react", "lib": ["es6"], "moduleResolution": "node", "noEmit": true, "strict": true, "target": "esnext" }, "exclude": [ "node_modules", "babel.config.js", "metro.config.js", "jest.config.js" ] }
3.創建一個jest.config.js
文件來配置Jest以使用TypeScript
module.exports = { preset: 'react-native', moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'], };
4.重命名一個JavaScript文件為 *.tsx
5.運行yarn tsc
以檢查新的TypeScript文件。
6.啟動項目
#啟動ios cd ts_react_native && npx react-native run-ios #啟動Android cd ts_react_native && npx react-native run-android
⒍設計架構
React Native的項目架構如圖所示
這與React App的常規架構幾乎一摸一樣,只是使用React Navigation作為路由庫。
我們必須充分利用代碼復用的優勢。在React Native中,我們同樣需要使用Redux對狀態進行全局管理。這樣的結構是為了React生態能夠簡單地移植。
⒎React Navigation
React Navigation是React Native上的一個路由解決方案,它在進行設計的時候,很多函數都是以高階函數的方式實現的,所以使用時會有很多不太直觀的地方。
yarn add react-navigation @types/react-navigation
將之前的index.tsx改名為List.tsx,因為后面需要實現列表頁,然后再新建一個index.tsx
import React from 'react'; import {StackNavigator} from 'react-navigation'; import List from './List'; const StackRouter = StackNavigator({ List:{ screen:List } },{ initialRouteName: 'List', }) const Router = () => (<StackRouter />) expect default Router
路由就算集成完畢了。
⒏Redux
添加依賴后,修改相關代碼。1.需要移除react-router相關代碼,2要修改在開發環境下連接Redux開發工具的函數。
src/store/index.ts
import {applyMiddleware, combineReducers, createStore} from 'redux'; import {composeWithDevTools} from 'redux-devtools-extension'; import {persistReducer,persistStore,PersistConfig} from 'redux-persist'; import storage from 'redux-persist/es/storage'; import thunk from 'redux-thunk'; import reducers from '../reducer'; const middleware = [thunk]; const rootReducer = combineReducers({ ...reducers, }) const persistConfig: PersistConfig = { key: 'root', storage, whitelist: ['draft'], } const persistedReducer: typeof rootReducer = persistedReducer(PersistConfig,rootReducer); const store = createStore( persistedReducer, __DEV__? composeWithDevTools(applyMiddleware(...middleware)) : applyMiddleware(...middleware), ) const persistor = persistStore(store); export{ store, persistor, }
src/index.tsx
import React from 'react'; import {StackNavigator} from 'react-navigation'; import List from './List'; import {Provider} from 'react-redux'; import {PersistGate} from 'redux-persist/integration/react'; import {persistor,store} from './store'; const StackRouter = StackNavigator({ List:{ screen:List } },{ initialRouteName: 'List', }) const Router = () => ( <Provider store={store}> <PersistGate loading={null} persistor={persistor}> <StackRouter /> </PersistGate> </Provider> ) expect default Router
這樣,我們就能最大限度地復用React App中的代碼了。
*可以使用react-native-debugger進行調試
⒐列表頁
實現列表頁需要連接Redux然后獲取數據,這里我們先用Text組件來循環渲染
這個地方需要注意,要全局修改網路請求的地址到localhost:3001,因為App上沒有跨域的限制,可以直接訪問。
所以我們先發一波網絡請求。
src/List.tsx
import React, { Component } from 'react'; import {Platform,StyleSheet,Text,View,TouchableOpacity} from 'react-native'; import {fetchList} from './action'; import {connect} from 'react-redux'; const mapStateToProps = (storeState,IStoreState) => ({ list: storeState.list, }) type IStateProps = ReturnType<typeof mapStateToProps> const mapDispatchToProps = { fetchList, } type IDispatchProps = typeof mapDispatchToProps type IProps = IStateProps & IDispatchProps class App extends Component<IProps> { componentDidMount(){ this.props.fetchList() } render(){ console.log(this.props.list) return( <View style={styles.container}> </View> ) } } export default connect<IStateProps,IDispatchProps>(mapStateToProps,mapDispatchToProps)(App) const styles = StyleSheet.create({ container:{ flex:1, justifyContent:"center", alignItems:"center", backgroundColor:'#F5FCFF', },v });
在Debugger工具中你可以看到Action的變化,但不能看到網絡請求。
有個小技巧,在Dubugger中點擊右鍵,選擇Enable Network Inspect就可以在Network Tab頁下查看網絡請求了。
到這里,你會發現所有的東西又回到了熟悉的React環境中。
⒑總結
如果你熟悉React,那么就已經入門React Native一半了。
如果了解在React下使用TypeScript,那么在React Native中使用React全家桶更是輕而易舉。
如果在React Native的開發中沒有使用TypeScript,在沒有嚴格類型檢查的情況下,在React Native中,空值或者異常值會直接導致Native運行環境的奔潰,代碼的質量把關比起Web環境要嚴苛了許多,這也是React Native項目最后必然都引入類型檢查工具的原因。
建議大家在創建React Native項目時,優先使用TypeSctipt,這可以避免很多由臟數據產生難以發覺的bug。