home 页面有时可以渲染,有时没有渲染,空白的,请求是正常的
来源:21-2 实战仿写小红书App-实现列表显示和分页加载

西瓜一号
2024-07-18
import { observable } from "mobx";
import apiConfig from "../../api/Apis";
import { request } from "../../utils/request"
const SIZE = 10;
export default class HomeStore {
page: number = 1;
@observable homeList: ArticleSimple[] = []; //@observable 装饰器,homeList变化会引起UI刷新的
@observable refreshing:boolean = false;
setPage = () => {
this.page = 1;
// this.requesHomeList();
}
requesHomeList = async () => {
if(this.refreshing === true){
return; //正在请求,不可以再次请求
}
try {
this.refreshing = true;
const params = {
page: this.page,
size: SIZE,
};
const { data } = await request(apiConfig.homeList.name, params);
console.log(data);
this.homeList = data;
if (data?.length){
// 有数据
if(this.page === 1){
this.homeList = data;
}else{
this.homeList = [...this.homeList,...data];
}
this.page = this.page + 1;
}else{
//无数据
if(this.page === 1){
this.homeList = [];
}else{
//已经加载完了,没有新数据了
console.log('已经加载完了,没有新数据了');
}
}
} catch (error) {
console.error(error);
} finally{
this.refreshing = false;
}
}
}
import React, { useEffect } from "react";
import { View, Text, StyleSheet, FlatList, Dimensions, Image } from "react-native";
import { observer, useLocalStore } from "mobx-react";
import { useLocalObservable } from 'mobx-react-lite';
import HomeStore from "./HomeStore";
import { TouchableOpacity } from "react-native-gesture-handler";
import icon_heart_empty from '../../assets/icon_heart_empty.png'
import icon_heart from '../../assets/icon_heart.png'
export default observer(() => {
const { width: SCREEN_WIDTH } = Dimensions.get('window')
// const store = useLocalObservable(() => new HomeStore());
const store = useLocalStore(() => new HomeStore());
useEffect(() => {
store.requesHomeList();
}, []);
const refreshNewData = () =>{
store.setPage();
store.requesHomeList();
console.log('refreshNewData')
}
const loadMoreData = () =>{
store.requesHomeList();
console.log('loadMoreData')
}
const renderItem = ({ item, index }: { item: ArticleSimple, index: number }) => {
const s = StyleSheet.create({
root: {
flexDirection: 'column',
width: SCREEN_WIDTH - 18 >> 1,
backgroundColor: 'white',
marginLeft: 6,
marginBottom: 6,
// height:260,
borderRadius:8,
overflow:'hidden' //子组件超出范围隐藏
},
img: {
width: '100%',
height: 240,
resizeMode: 'cover',
},
content: {
fontSize: 14,
fontWeight: 'bold',
color: '#333',
marginVertical:4,
marginHorizontal:12
},
layoutView: {
flexDirection: 'row',
width: '100%',
height: 40,
alignItems: 'center',
// backgroundColor: 'pink',
paddingHorizontal: 10,
marginBottom:10,
},
avatar: {
width: 20,
height: 20,
resizeMode: 'contain',
borderRadius: 10,
},
userName: {
fontSize: 12,
color: '#999',
flex: 1,
marginLeft:6
},
favoriteCount: {
fontSize: 14,
color: '#999',
marginLeft:4
},
favoriteButton: {
},
favoriteImg: {
width: 20,
height: 20,
resizeMode:'contain',
}
});
return (
<View style={s.root}>
<Image style={s.img} source={{ uri: item.image }} />
<Text style={s.content}>{item.title}</Text>
<View style={s.layoutView}>
<Image style={s.avatar} source={{ uri: item.avatarUrl }} />
<Text style={s.userName}>{item.userName}</Text>
<TouchableOpacity style={s.favoriteButton}>
<Image style={s.favoriteImg} source={item.isFavorite ? icon_heart : icon_heart_empty} />
</TouchableOpacity>
<Text style={s.favoriteCount}>{item.favoriteCount}</Text>
</View>
</View>
);
};
const Footer = () => {
return (
<Text style={s.footer}>
没有数据了
</Text>
);
};
return (
<View style={s.root}>
<FlatList
style={s.flatList}
contentContainerStyle={s.contentContainerStyle}
data={store.homeList}
extraData={[store.refreshing]}
renderItem={renderItem}
numColumns={2}
refreshing={store.refreshing}
onRefresh={refreshNewData}
// keyExtractor={(item, index) => `${index} - ${item.title}`}
onEndReachedThreshold={0.1}
onEndReached={loadMoreData}
ListFooterComponent={<Footer />}
/>
</View>
);
});
const s = StyleSheet.create({
root: {
width: '100%',
height: '100%',
backgroundColor: '#f0f0f0',
flexDirection: 'column',
justifyContent: 'center',
alignItems: 'center',
},
flatList: {
width: '100%',
height: '100%',
},
contentContainerStyle:{
paddingTop:6,
},
footer:{
width:'100%',
fontSize:14,
color:'#999',
marginVertical:12,
textAlign:'center',
textAlignVertical:'center',
},
});
还有上拉加载更多请求数据有了,不能刷新UI
多次测试发现,没有观察到store的数据变化,导致没有刷新UI,要是store.homeList初始化写死数据,渲染是正常的,在store里面打印homeList也是有数据的,就是在home页面没法触发渲染
写回答
1回答
-
FE大公爵
2025-04-22
看了代码,可能有两个原因。你分别试一下。
1、你集成的是新版本mobx,但是代码用的还是老的api,你尝试用新版api看看。
2、你的store里,在接口返回数据时,多写了一个this.homeList=data,把这个去掉,下面有针对分页的赋值处理。
00
相似问题