iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 6
0
Modern Web

我不用Expo啦,React Native!系列 第 6

[Day6] 訂定資料格式-TypeScript:型別判斷

  • 分享至 

  • xImage
  •  

今日關鍵字:TypeScript


接續昨天icon尚未設定完成
先自定一個對應各個畫面的陣列

const routes = [
  {
    name: 'Home',
    id: 'Home',
    icon: {
      ios: 'ios-home',
      android: 'home',
    },
    component: <HomeScreen />,
  },
  {
    name: 'Search',
    id: 'Search',
    icon: {ios: 'ios-search', android: 'search'},
    component: <SearchingScreen />,
  }
  ......
];

順便定義要用到的icon

這時就可以用這個陣列來跑icon對應的圖案
https://ithelp.ithome.com.tw/upload/images/20200906/20121828EBYiqORv7c.png
嗯紅字逐漸增加...

這裡從react-native插入了Platform
作用是判斷app平台

import {Platform} from 'react-native';

console.log(Platform.OS) // 'ios','android'

要處理紅字之前要先認識一下TS


TypeScript:宣告變數型態

在ES6下的JS如果想要取變數時

let a = 1

這種取法可以看出來,無法預設變數a的型態

a = 'test' // ok

如果在TS則可以宣告變數的型態

let a: number = 1

如果這時想改變變數的值

a = 2 // ok
a = 'test' // fail

如果只寫這樣的話

let a = 1

TS會自動推斷a的型態為number
所以如果這時想改變變數的值為string

a = 'test' // fail

這個強型態語言的特點
比起JS管理變數容易了許多

Interface

除了const.let之外
TS還有個interface
作用為給物件訂定需要實作的方法/images/emoticon/emoticon13.gif
而我們可以善用這個
訂定屬於自己的資料格式
(給資料訂定必備的屬性)

可以先如此宣告

interface Mydata {
  title: string
  index: number
  content?: string
}

其中?是代表非必要的屬性

這時如果要取變數

let a: Mydata = {} // fail

let b: Mydata = {
  title: 'test',
  index: 2,
  content: 'content'
} // ok

let c: Mydata = {
  title: 'test',
  index: 3,
} // ok

let d: Mydata = {
  title: 'test',
  index: '4',
  content: 'content'
} // fail

當然interface也能export,很多時候會直接import寫好的來用


這時回頭來看看出現的紅字
https://ithelp.ithome.com.tw/upload/images/20200906/20121828b31oxsjPWO.png

如果iconName沒有預設值的話可能會undefined
所以可以給個初始值就能解決問題了

let iconName = 'ios-list';

至於另一個紅字
https://ithelp.ithome.com.tw/upload/images/20200906/20121828fkbhjpoe6J.png
由於我們會使用的平台這裡只有兩個才會報錯
可以用個三元運算子解決

for (let i = 0; i < routes.length; i += 1) {
  if (route.name === routes[i].name) {
    iconName = focused
      ? routes[i].icon[Platform.OS === 'ios' ? 'ios' : 'android']
      : `${
        routes[i].icon[Platform.OS === 'ios' ? 'ios' : 'android']
        }-outline`;
    break;
  }
}

同時下面的

<Tab.Screen name="Home" component={HomeScreen} />
<Tab.Screen name="Searching" component={SearchingScreen} />
<Tab.Screen name="Favorite" component={FavoriteScreen} />
<Tab.Screen name="Settings" component={SettingsScreen} />

可以利用剛剛訂定的陣列用map處理

{routes.map((route) => {
  const EachScene = () => route.component;
  return (
    <Tab.Screen
      name={route.name}
      component={EachScene}
      key={route.id}
    />
  );
})}

被map的元件最外層要設置唯一的key
避免沒必要的重新渲染

成果https://ithelp.ithome.com.tw/upload/images/20200906/20121828gb7ODU6wxB.png

謎:啊interface怎麼沒用到?
我:概念一起講,明天會用啦/images/emoticon/emoticon16.gif


明天的目標是首頁的畫面

參考:TypeScript


上一篇
[Day5] 在導覽列加入圖示
下一篇
[Day7] 訂定資料格式-2
系列文
我不用Expo啦,React Native!33
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言