React-Native:如何使用异步函数获取平面列表的数据

React-Native: How to use async functions to get data for flatlist

我对 React Native 还很陌生,最近一直在开发时间表应用程序。我正在尝试从数据库中获取数据并将其显示在平面列表中,但是平面列表一直显示为空。 我不太确定我做错了。当我将数据记录到控制台时,它会将正确的数据记录到控制台,但是当我尝试使平面列表呈现数据时,它显示为空

timesheets.js

export default function TimesheetScreen({ navigation }) {
      
      const getData = async () => {
        data = await getTimesheets()
        console.log(data);
        return data;
      }

      const timesheetsData = getData();
      
      const Item = ({ name }) => (
        <View style={styles.body}>
          <Text styles={styles.bodyText}>{name}</Text>
        </View>
      );
        
       const renderItem = ({ item }) => (
        <TouchableOpacity onPress={() =>navigation.navigate('DetailScreen', item)}>
          <Item name={item.name +": " + item.date}/>
        </TouchableOpacity>
      );

            return (
              <View style={styles.container}>
                <View style={styles.header}>
                  <Text style={styles.headerText}>My Timesheets</Text>
                  
                </View>
                <TextInput 
                  style={styles.searchBackground}
                  placeholder='Enter Employee Name'
                  onEndEditing={text=>console.log(text)}/>
                <FlatList
                data={timesheetsData}
                renderItem={renderItem}
                keyExtractor={item => item.clockID}
                />
              </View>
            );
          }
    

正在查询数据库的函数

export const getTimesheets = async () =>{
      //gets all employee records from collection employees
    var allTimesheets= await firebase.firestore()
    .collection('employees')
    .get();
    var timesheetsArray=[];
    for(let i=0;i<(allTimesheets.docs).length;i++){
        let timesheetsData=(allTimesheets.docs[i]).data();
       timesheetsArray.push(timesheetsData);
 
    }

谢谢

由于 getData 是异步的,因此常量 timesheetsData 在第一个渲染周期中不包含任何内容,并且由于数据准备就绪时您不会触发 state 更改,因此不会触发重新渲染,导致空 FlatList.

这可以通过使用 useEffect 并引入如下状态变量来解决。

export default function TimesheetScreen({ navigation }) {

      const [timesheetsData, setTimeSheetsData] = useState()

      useEffect(() => {
         const getData = async () => {
           data = await getTimesheets()
           console.log(data);
           setTimeSheetsData(data);
         }

         getData()
      }, [])
      
      const Item = ({ name }) => (
        <View style={styles.body}>
          <Text styles={styles.bodyText}>{name}</Text>
        </View>
      );
        
       const renderItem = ({ item }) => (
        <TouchableOpacity onPress={() =>navigation.navigate('DetailScreen', item)}>
          <Item name={item.name +": " + item.date}/>
        </TouchableOpacity>
      );

            return (
              <View style={styles.container}>
                <View style={styles.header}>
                  <Text style={styles.headerText}>My Timesheets</Text>
                  
                </View>
                <TextInput 
                  style={styles.searchBackground}
                  placeholder='Enter Employee Name'
                  onEndEditing={text=>console.log(text)}/>
                <FlatList
                data={timesheetsData}
                renderItem={renderItem}
                keyExtractor={item => item.clockID}
                />
              </View>
            );
          }

我注意到您缺少状态。 在 React 中,每次状态更改都会使 UI re-render 具有新的状态数据。

获得数据库结果后,您必须re-render 使用状态变量筛选。 这个可以通过React.useState()钩子函数解决

所以,请尝试这种方式。

 export default function TimesheetScreen({ navigation }) {
          
          const getData = async () => {
            data = await getTimesheets()
            console.log(data);
            return data;
          }

          const [data, setData] = React.useState([]);
    
          

          React.useEffect(async () => {
              const timesheetsData = await getData();
              setData(timesheetsData);
          });
          
          const Item = ({ name }) => (
            <View style={styles.body}>
              <Text styles={styles.bodyText}>{name}</Text>
            </View>
          );
            
           const renderItem = ({ item }) => (
            <TouchableOpacity onPress={() =>navigation.navigate('DetailScreen', item)}>
              <Item name={item.name +": " + item.date}/>
            </TouchableOpacity>
          );
    
          return (
            <View style={styles.container}>
              <View style={styles.header}>
                <Text style={styles.headerText}>My Timesheets</Text>
    
              </View>
              <TextInput 
                style={styles.searchBackground}
                placeholder='Enter Employee Name'
                onEndEditing={text=>console.log(text)}/>
              <FlatList
              data={data}
              renderItem={renderItem}
              keyExtractor={item => item.clockID}
              />
            </View>
          );
 }