使用TypeScript創建React Native


⒈初始化 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。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM