获取单个数据后如何强制Flatlist重新渲染? [英] How to force Flatlist to re-render after getting a single data?

查看:33
本文介绍了获取单个数据后如何强制Flatlist重新渲染?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我从服务器获取单个数据并将它们设置为状态并传递给数据道具时,我遇到了 flatlist 问题,我在渲染中看不到任何更新我正在添加一些加载,如果我'd 没有收到任何数据我显示了一个让我们说指示器"所以指示器消失,我看到黑屏!!

I've faced an issue with flatlist when I get single data from the server and set these into state and passes into data props, I can't see any update in the render "I'm adding some Loading if I'd not received any data I show an let's say Indicator" so the indicator disappears and I see blank screen!!

仅供参考,当我启用热重载并在我的 IDE 中按保存时,我可以在我的屏幕中看到单个数据!

FYI, When I enable Hot Reloading and just press Save in my IDE I can see the single Data in my Screen!

那么我怎样才能强制它出现数据!

So how can I force it to appear the data!

代码

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

You have used extra data props but the issue is flatlist does a shallow data comparison so when the length of users changes it won't affect the flatlist so replace it with this.state.users

extraData={this.state.users}

您可以在文档中看到它说 flatlist 是 PureCompoment 的实现,而 PureComponent 进行了浅层比较,这就是它不重新渲染的原因.https://reactnative.dev/docs/flatlist#extradata

You can see in the documentation it says flatlist is implementation of PureCompoment and PureComponent does a shallow comparison thats the reason it is not re-rendering. https://reactnative.dev/docs/flatlist#extradata

这篇关于获取单个数据后如何强制Flatlist重新渲染?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆