iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 7
0
Modern Web

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

[Day7] 訂定資料格式-2

今日關鍵字:interface


建立動畫格式

延續昨天的interface
首先幫我的動畫資料訂定格式
https://ithelp.ithome.com.tw/upload/images/20200907/20121828IcdtOQ5AxW.png

這時如果要設定一個動畫陣列

[Anime1 ,Anime2......]

這種時候該如何宣告陣列呢?

const AnimeArray : Array<Anime> = []

這個<>可以理解為塞進去的規定值
在這個情況下就是限定這是一個Anime的陣列

由於首頁的資料在呈現時
預定是要有七個輪播(對應週一到週日)
每一個輪播的資料來源都是當日的動畫列表
所以寫起來就是

原始動畫列表

Array<Anime>

首頁列表

Array<Array<Anime>>

這邊我用了一個Promise來模擬未來接API的狀況
不過這時來說是個完全沒必要的操作......(想說接個then就有帥氣的感覺了/images/emoticon/emoticon07.gif)
這邊直接用個陣列來跑就可以了/images/emoticon/emoticon36.gif

https://ithelp.ithome.com.tw/upload/images/20200907/2012182837nDo6jmJg.png
這裡實現的功能有幾個

  1. 將原始動畫資料按週一週二分成七個
  2. 每個動畫列表依評價排列

這裡用到了一些東西


State

state是各個component中的狀態
與普通變數最大不同的時
如果將state顯示於畫面上
當state做修改時畫面也會立即修改(響應式)

各個框架中state的更新策略是不同的
react的Function Component使用useState這個hook函數作更新

import React ,{ useState } from 'react'
...
const [data,setData]=useState<T>(初始值)

data就是狀態本身
setData是更新函式

setData(newData)

<T>不見得需要加,因為TS會根據初始值推斷型態

有一點要注意的
setData這個更新狀態函式是非同步的
例如想比較新舊狀態大小

const [state,setState]=useState(oldState)
...
const memo=state
setState(newState)

if(state>memo){
  console.log('plus')
}
if(state<memo){
  console.log('minus')
}

// 什麼都沒發生

實際上的執行順序是
if=>seState
而不是原本以為的
setState=>if
所以要避免用同步的方式直接取用新狀態

如果非得要直接取用
當然也是有方法
實際上setState內是可以設置callback的

const [state,setState]=useState(oldState)
...
const memo=state
setState(oldState=>{

  if(newState>memo){
    console.log('plus')
  }
  if(newState<memo){
    console.log('minus')
  }

  return newState
})

// plus or minus

當然這個例子很明顯就是有別的寫法可以避免啦...

順帶一提setState設置參數為callback時

setState(s=>s+1)

這個s其實就是舊的state


moment.js

是一個專門處理時間資料的函式庫
之後可能會再提,這裡先草草帶過
詳細的使用請看這裡
這裡是用來把週一週二等當作index使用


useMemo

為React的hook函數之一
作用為依賴值改變時才重新進行計算
反過來說就是依賴值沒改變時不會重新計算
省下昂貴(?)的計算

const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);

當a或b改變時才重新計算


優化

補充了一些東西後
回頭進行動畫列表的優化
由於把動畫列表拆成七個的計算量不小
這裡使用useMemo來優化
https://ithelp.ithome.com.tw/upload/images/20200907/20121828b6IOvvgBYE.png

然後這裡突然發現我想寫的依評價排列的地方是無效的
裡面的比較應該要是a-b的形式
應該要這麼更改
https://ithelp.ithome.com.tw/upload/images/20200907/201218281iz6U0MFGA.png


明天預計來講輪播
原本是今天要寫的
沒想到資料排序寫起來頗長的.../images/emoticon/emoticon02.gif

參考:


上一篇
[Day6] 訂定資料格式-TypeScript:型別判斷
下一篇
[Day8] 輪播:神奇的上下交錯
系列文
我不用Expo啦,React Native!33

尚未有邦友留言

立即登入留言