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

在移动端页面获取屏幕的宽度一般是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"
}} />

例子二:

alignSelf 不遵从父元素的排列规则,按自己的规则来


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

例子三: marginRight:'auto'自动边距

<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>
03-05 14:06