今日關鍵字: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對應的圖案
嗯紅字逐漸增加...
這裡從react-native插入了Platform
作用是判斷app平台
import {Platform} from 'react-native';
console.log(Platform.OS) // 'ios','android'
要處理紅字之前要先認識一下TS
在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管理變數容易了許多
除了const
.let
之外
TS還有個interface
作用為給物件訂定需要實作的方法
而我們可以善用這個
訂定屬於自己的資料格式
(給資料訂定必備的屬性)
可以先如此宣告
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寫好的來用
這時回頭來看看出現的紅字
如果iconName沒有預設值的話可能會undefined
所以可以給個初始值就能解決問題了
let iconName = 'ios-list';
至於另一個紅字
由於我們會使用的平台這裡只有兩個才會報錯
可以用個三元運算子解決
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
避免沒必要的重新渲染
成果
謎:啊interface怎麼沒用到?
我:概念一起講,明天會用啦
明天的目標是首頁的畫面
參考:TypeScript