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

发布于 2025-01-14 00:34:27 字数 1990 浏览 3 评论 0原文

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

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);
 
    }

谢谢

I'm pretty new to react native, and have been working on a timesheets app recently. I'm trying to get data from a database and display it in a flatlist, however the flatlist keeps appearing empty.
I'm not really sure I'm doing wrong. When I log the data to the console it logs the correct data to the console but when I try to make the flatlist render the data it appears empty

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>
            );
          }
    

the function that is querying the database

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);
 
    }

Thank You

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

强者自强 2025-01-21 00:34:27

由于 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>
            );
          }

Since getData is async, the constant timesheetsData does not contain anything in the first render cycle and since you are not triggering a state change when the data is ready, no rerender is triggered, resulting in an empty FlatList.

This could be solved by using a useEffect and introducing a state variable as follows.

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>
            );
          }
衣神在巴黎 2025-01-21 00:34:27

我注意到你缺少状态。
在 React 中,每次状态更改都会使用新的状态数据重新渲染 UI。

获取数据库结果后,您必须使用状态变量重新渲染屏幕。
这可以通过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>
          );
 }

I have noticed that you are missing state.
In React, every time state is changed makes UI re-render with new state data.

After getting database result, you have to re-render screen with state variable.
This can be solved by React.useState() hook function.

So, please try this way.

 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>
          );
 }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文