React-native 開發小技巧

HappyCodingTop發表於2022-01-01

1. isFocused

我們知道對於App來說,對於頁面的跳轉不像PC端,Pc端如果跳轉頁面,則上一個頁面會解除安裝,APP則不然,它是一個頁面蓋在另一個頁面上面,怎麼理解呢,就是當前頁面蓋在上一個頁面上。
那這個特性也就會導致我們開發的時候需要去考慮規避二件事:
1.頁面不會解除安裝,返回的時候,不會重新請求頁面
2.或者說有的是高消耗的頁面不在當前頁面了,也會一直在消耗手機效能
這時候就要隆重介紹一個新的屬性了:isFocused
這個屬性可以讓我們得知:是否在當前頁面,如果是:true,否則就是false
長話短說直接上程式碼:

  1. 解決返回頁面不會重新整理的問題

    import {useIsFocused} from "@react-navigation/native";
    const isFocused = useIsFocused()
    useEffect(()=>{
     if(isFocused){
         getListData()
     }
    },[isFocused])
  2. 解決不在高消耗頁面,還在消耗

    isFocused && (
     <Camera onCodeRead={(code)=>{
       const url = parse(code);
       navigate('WebScreen',{uri:url})
      }}/>
      )

2.react-native flex佈局

一般我們使用flex佈局的主軸是row,但是在react-native中主軸是column
為什麼會是這樣呢,因為手機橫屏沒有豎屏長,react-native才故意這樣設計的。下面的例子是相容性的展示九宮格,每行三個。
例子1

Image.png

在移動端頁面獲取螢幕的寬度一般是vw,vh,但是在RN中則是這樣的:

import {Dimensions} from 'react-native'
const {width:screenWidth,height:screenHeight} = Dimensions.get('window')
export {screenHeight,screenWidth};

然後設定間隙和每個盒子的寬高:
整螢幕的寬度 - 兩邊的padding - 頭像的寬度-頭像右側的寬度-兩個間隙

let cellGap = 5;
let cellWidth = (screenWidth - 10*2-32-10-cellGap*2)/3

<View style={{
    width:cellWidth,
    height:cellHeight,
    backgroundColor:"blue"
}} />

例子二:
Image.png

alignSelf 不遵從父元素的排列規則,按自己的規則來


<View style={{
    width:cellWidth,
    height:cellHeight,
    backgroundColor:"blue",
    alignSelf:'flex-end',
}} />

例子三: marginRight:'auto'自動邊距

企業微信截圖_16411939908399.png

<View 
     style={{
         width:cellWidth,
         height:cellHeight,
         marginRight:'auto',
         backgroundColor:'yellow'
        }}
  />

利用useState對資料來源過濾或初始化

const [feelLikes,setFeelLikes] = React.useState(
    item.feelLikes?Map(({useId})=>useId)||[],
)

qs

專案中Get請求,往介面傳參一般是key=value&key=value格式,對於多引數,或條件引數多有不便,
可以使用qs(queryString)外掛
-- qs.stringify() 將物件解析成url
-- qs.parse() 是將url解析成物件


  import qs from 'qs'

  const {data} = await get(
      `/feed?${qs.stringify({
          offset:isRefresh?0:listData.length,
          limit,//跨度值
          useId:showMyself?user.id:undefined
      })}`
  )

useRef用於成員變數

通常我們我們在元件內let 定義一個狀態變數,平常使用沒什麼問題,
但是當我們想要頻繁使用的時候(在介面還沒反應過來的時候),
第一次後的每一次都會給這個變數重新初始化,那這個狀態變數對於整個邏輯來說就亂了,所以這裡需要使用useRef來定義成員變數

const isEndReached = React.useRef(false)
const isFetching = React.useRef(false)

if(isRefresh){
    currentCount = data.rows.length;
    setListData(data.rows)
}else{
    currentCount = data.rows.length + listData.length
}
if(currentCount>=data.count){
    isEndReached.current = true
} else {
    isEndReached.current = false
}

多個相同的子元件的條件下,在父元件中維護一個變數

子元件 FeedItem

<View style={StyleSheet.metaTextContainer}>
    <Text style={StyleSheet.metaText}>
        {fromNow}
    </Text>
    <TouchableOpacity
      style={styles.likeButton}
      onPress={onPress}
    >
        <Icon 
            style={[styles.likeIcon,choosen&&styles.action]}
            name={choosen?'heart':'heart-o'}
        />
        <Text style={styles.metaText}>{feedLikes.length}</Text>
    </TouchableOpacity>
</View>

父元件

<SafeAreaView
    style={styles.container}
    <FlatList <Feed>
        data={listData}
        refreshing={loading === 'refresh'}
        onRefresh={()=>getListData(true)}
        keyExtractor={(item)=>String(item.id)}
        renderItem={({item,index})=>(
            <FeedItem 
                choosen={choseIndex === index}
                item={item}
                onPress={()=>setChoseIndex(index)}
            />
        )}
    />
>

</SafeAreaView>

相關文章