1. isFocused
We know that for the App, the page jump is not like the PC side. If the PC side jumps to the page, the previous page will be uninstalled, but the APP is not. It is a page on top of another page. How do you understand it? That is, the current page is overlaid on the previous page.
Then this feature will also cause us to consider two things to avoid when developing:
1. The page will not be unloaded, and will not be re-requested when returning
2. In other words, if the high-consumption page is no longer on the current page, it will continue to consume the performance of the mobile phone.
is about to introduce a new attribute: isFocused
This attribute allows us to know: whether it is on the current page, if it is: true, otherwise it is false
To make a long story short, go directly to the code:
Solve the problem that the page will not refresh when returned
import {useIsFocused} from "@react-navigation/native"; const isFocused = useIsFocused() useEffect(()=>{ if(isFocused){ getListData() } },[isFocused])
Solve the problem of not being a high-consumption page, but still consuming
isFocused && ( <Camera onCodeRead={(code)=>{ const url = parse(code); navigate('WebScreen',{uri:url}) }}/> )
2.react-native flex layout
Generally, the main axis of flex layout is row, but in react-native, the main axis is column
Why is this the case? Because the horizontal screen of the mobile phone is not as long as the vertical screen, react-native designed it like this on purpose. The following example shows the compatibility of nine square grids, with three in each row.
example 1
The width of the screen obtained on the mobile terminal page is generally vw, vh, but it is like this in RN:
import {Dimensions} from 'react-native'
const {width:screenWidth,height:screenHeight} = Dimensions.get('window')
export {screenHeight,screenWidth};
Then set the gap and the width and height of each box:
The width of the entire screen-padding on both sides-the width of the avatar-the width of the right side of the avatar-two gaps
let cellGap = 5;
let cellWidth = (screenWidth - 10*2-32-10-cellGap*2)/3
<View style={{
width:cellWidth,
height:cellHeight,
backgroundColor:"blue"
}} />
example two:
alignSelf does not follow the arrangement rules of the parent element, according to its own rules
<View style={{
width:cellWidth,
height:cellHeight,
backgroundColor:"blue",
alignSelf:'flex-end',
}} />
example three: marginRight:'auto' automatic margin
<View
style={{
width:cellWidth,
height:cellHeight,
marginRight:'auto',
backgroundColor:'yellow'
}}
/>
Use useState to filter or initialize data sources
const [feelLikes,setFeelLikes] = React.useState(
item.feelLikes?Map(({useId})=>useId)||[],
)
qs
In the Get request of the project, the parameters passed to the interface are generally in the format of key=value&key=value, which is inconvenient for multiple parameters or conditional parameters.
You can use the qs(queryString) plugin
- qs.stringify() parses the object into a url
- qs.parse() is to parse the url into an object
import qs from 'qs'
const {data} = await get(
`/feed?${qs.stringify({
offset:isRefresh?0:listData.length,
limit,//跨度值
useId:showMyself?user.id:undefined
})}`
)
useRef for member variables
Usually we define a state variable in let in the component, and there is no problem in normal use.
But when we want to use it frequently (when the interface has not yet reacted),
This variable will be reinitialized every time after the first time, then this state variable is messed up for the whole logic, so here you need to use useRef to define the member variable
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
}
Maintain a variable in the parent component under the condition of multiple identical child components
Subcomponent 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>
parent component
<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>
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。