javascript - 获取单个数据后如何强制 Flatlist 重新渲染?
问题描述
当我从服务器获取单个数据并将这些数据设置为状态并传递给数据道具时,我遇到了平面列表的问题,我在渲染中看不到任何更新“如果我没有收到,我正在添加一些加载我显示的任何数据让我们说指标”,因此指标消失,我看到空白屏幕!
仅供参考,当我启用热重载并在我的 IDE 中按保存时,我可以在我的屏幕中看到单个数据!
那我怎么能强迫它出现数据!
代码
import React, { Component } from "react";
import firebase from "react-native-firebase";
import Icon from "react-native-vector-icons/Ionicons";
import _ from "lodash";
import {
View,
Text,
StyleSheet,
FlatList,
TouchableOpacity,
Image,
Dimensions
} from "react-native";
const { width } = Dimensions.get("screen");
class ListChats extends Component {
constructor(props) {
super(props);
this.state = {
users: [],
noChat: true
};
}
_getUsers = () => {
let currentUser = firebase.auth().currentUser.uid;
let ref = firebase.database().ref(`Messages/${currentUser}`);
let usersKeys = [];
ref.once("value").then(snapshot => {
snapshot.forEach(childsnap => {
usersKeys.push(childsnap.key);
});
let usernames = [];
usersKeys.forEach(key => {
firebase
.database()
.ref("users")
.child(key)
.once("value")
.then(usersShot => {
let username = usersShot.val().username;
usernames.push({ username: username, key: key });
});
});
this.setState({ users: usernames,noChat: false });
});
};
componentDidMount() {
this._getUsers();
}
render() {
if (this.state.noChat) {
console.log("IF", this.state.users);
return (
<View style={styles.container}>
<Image
style={{
width,
height: width * 0.7,
resizeMode: "contain"
}}
source={require("../../assets/empty.gif")}
/>
<Text style={{ alignSelf: "center" }}>No Chats Found</Text>
</View>
);
} else {
console.log("Else", this.state.users);
return (
<View style={styles.container}>
<FlatList
key={Math.random() * 1000}
extraData={this.state} // I'm already added
data={this.state.users}
contentContainerStyle={{ flexGrow: 1 }}
renderItem={({ item }) => {
return (
<TouchableOpacity
onPress={() =>
this.props.navigation.navigate("ChatDetails", {
Key: item.key,
userName: item.username
})
}
>
<View style={styles.parent}>
<Icon name="ios-contact" size={50} color="#4d8dd6" />
<View
style={{
flex: 1,
justifyContent: "flex-start",
alignItems: "flex-start",
marginHorizontal: 25
}}
>
<Text
style={{
color: "#000",
fontSize: 17
// marginHorizontal: 25
// alignSelf: "stretch"
}}
>
{item.username}
</Text>
{/* <Text
style={{
color: "#a1a1a1",
marginHorizontal: 35,
marginVertical: 5,
alignSelf: "stretch"
}}
numberOfLines={1}
lineBreakMode="tail"
>
{item.lastMssg.text}
</Text> */}
</View>
<Icon name="ios-chatboxes" size={25} color="#d6d6d6" />
</View>
</TouchableOpacity>
);
}}
keyExtractor={(item, index) => index.toString()}
/>
</View>
);
}
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center"
},
parent: {
flexDirection: "row",
justifyContent: "space-between",
alignItems: "center",
paddingVertical: 25,
marginHorizontal: 15,
borderBottomWidth: 1,
borderBottomColor: "#eee"
}
});
export default ListChats;
解决方案
您使用了额外的数据道具,但问题是 flatlist 进行了浅层数据比较,因此当用户的长度发生变化时,它不会影响 flatlist,因此将其替换为 this.state.users
extraData={this.state.users}
您可以在文档中看到它说 flatlist 是 PureCompoment 的实现,而 PureComponent 进行了浅层比较,这就是它不重新渲染的原因。 https://reactnative.dev/docs/flatlist#extradata
推荐阅读
- ios - 尝试将 json 解码为 NSManagedObject 时,给定数据不包含顶级值错误
- c# - 如何将字节数组转换回 asp net core 中的视图可消耗的图像?
- java - gradle javaexec 错误“不允许直接使用'apiElements'”- Gradle 5.4.1
- sql - 如何掩盖一个值以表示其他含义
- prometheus - 有人使用 $__interval 对固定值进行范围选择吗?
- spring-boot - 分区时间在 Spring 集成测试中转换为 UTC
- ios - 使用 twilio 向我的个人号码进行语音通话
- laravel - 我不想使用 laravel 在数组中显示空值
- python - psycopg2如何检查是否存在具有相同属性值的记录
- javascript - 如何解决素数索引元素的总和?