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

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

问题描述

当我从服务器获取单个数据并将其设置为状态并传递给数据道具时,我遇到了平面列表问题,我无法在渲染器中看到任何更新. d没有收到任何数据,我显示指示器",所以指示器消失了,我看到黑屏!

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

那么我该如何强迫它显示数据!

代码

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;

解决方案

强制重新提交平面列表.只需在状态中添加一个布尔值就可以说"forceUpdate",并且每当有项目添加到平面列表数据时,都将切换该布尔值并将其传递给FlatList的额外数据而不是状态.

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!!

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!

Code

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;

解决方案

to force the flatlist re-render. just add a boolean lets say "forceUpdate" to your state and whenever an item is added to flatlist data toggle that boolean and pass that to the extra data of your FlatList instead of the state.

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

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