简体   繁体   English

需要帮助弄清楚我的数据操作/道具传递 React-Native/react-native-calendars

[英]Need help figuring out my data manipulation/prop passing React-Native/react-native-calendars

I am using react-native-calendars , aws-amplify , moment and uuid to fetch data, display date data as dots marked on the calendar and then allow the user to open a modal with that dates items from the query in my React Native (Expo) app.我正在使用react-native-calendarsaws-amplifymomentuuid来获取数据,将日期数据显示为日历上标记的点,然后允许用户打开一个模式,其中包含来自我的 React Native 查询中的日期项(世博会)应用程序。 I am getting an error, which isn't making much sense to me, I think it's the way I'm handling data manipulation/processing or property passing:我收到一个错误,这对我来说没有多大意义,我认为这是我处理数据操作/处理或属性传递的方式:

TypeError: undefined is not an object (evaluating 'item.createdAt')

This may be a long explanation, but I will explain to the best of my ability what's happening and where I think the error is coming from.这可能是一个很长的解释,但我会尽我所能解释发生了什么以及我认为错误来自哪里。

I have a query that returns a list of items, in this case they are notifications that have been sent to the user.我有一个返回项目列表的查询,在这种情况下,它们是已发送给用户的通知。 I have this function which handles getting the data and structuring it so that I can pass the items to a sub-component.我有这个 function,它处理获取数据和构建数据,以便我可以将项目传递给子组件。 Here is how I am querying the info and how I'm storing the data.以下是我如何查询信息以及如何存储数据。

CalendarCard.js (first half) CalendarCard.js (上半场)

import React, { useEffect, useState } from "react";
import moment from 'moment';
import 'react-native-get-random-values';
import { v4 as uuidv4 } from 'uuid';
import { API } from "aws-amplify";
import { listUserNotifications } from '../../graphql/queries';

...

const CalendarCard = (
    {
        showCalendarInfoModal,
        showDayModal,
        setDayNotificationItems,
    }) => {

    const [markedDates,setMarkedDates] = useState();
    const [notificationItems, setNotificationItems] = useState();

    const currentMonth = moment().startOf('month').toISOString();
    const now = new Date().toISOString();

    useEffect(() => {
        const recordInitNotifications = (notifications) => {
            notifications.forEach((item,i) => {
                let id = uuidv4().toString();
                let createdAt = item.createdAt;
                let notificationDate = moment(createdAt).format('YYYY-MM-DD');
                let notificationId = notificationDate+id;
                
                setMarkedDates(prev => ({
                    ...prev,
                    [notificationDate]: {marked: true, dotColor: 'grey'}
                }));
                setNotificationItems(prev => ({
                    ...prev,
                    [notificationId]: {[i]: item}
                }));
            });
        };

        const currentNotifications = async () => {
            const initNotificationData = await API.graphql({
                query: listUserNotifications,
                variables: {
                    filter: {
                        createdAt: {
                            between: [currentMonth,now]
                        }
                    }
                },
                authMode: 'AMAZON_COGNITO_USER_POOLS'
            });

            const initNotifications = initNotificationData.data.listUserNotifications.items;
            recordInitNotifications(initNotifications);
        };

        currentNotifications().catch(console.error);
    }, []);
...
// continued below

The result of the above sets my notificationItems variable as follows when I log it:上面的结果在我记录它时将我的notificationItems变量设置如下:

Object {
  "2022-04-096d64e695-c377-4790-88bc-4de803f63028": Object {
    "0": Object {
      "PushToken": "ExponentPushToken[*********************]",
      "StackName": "Everydaytest",
      "StackSchedule": "{\"Everyday\":{\"dw\":[6,7,1,2,3,4,5],\"type\":\"DAY_WEEK\",\"startDate\":\"2022-04-09T15:00:00.000Z\"}}",
      "StackScheduleName": "Everyday",
      "UserID": "user",
      "createdAt": "2022-04-09T15:00:22.504Z",
      "id": "ee520f0a-cd93-47f9-954d-0c5f741daaa7",
      "lastReceipt": "{\"stack\":\"patrick2022-04-09T14:52:37.519Z<139029b5-4402-4c08-b41f-b7653e64cb93>ba7cb97d-d6db-4086-82dd-b6a8c79712e5\",\"ticket\":{\"id\":\"e1ba6799-0a03-4126-a1fc-6fc4f39308d2\",\"status\":\"ok\"}}",
      "lastReceiptCreated": "2022-04-09T15:00:22.504Z",
      "owner": "user",
      "updatedAt": "2022-04-09T15:00:22.504Z",
    },
  },
  "2022-04-10213a8a85-7a0a-4e97-80c4-36711381f01f": Object {
    "4": Object {
      "PushToken": "ExponentPushToken[*********************]",
      "StackName": "Pasta",
      "StackSchedule": "{\"2 on, 1 off weekdays\":{\"dw\":[0,1,2,3],\"type\":\"DAY_WEEK\",\"startDate\":\"2022-03-13T11:00:00.000Z\"}}",
      "StackScheduleName": "2 on, 1 off weekdays",
      "UserID": "user",
      "createdAt": "2022-04-10T11:00:23.093Z",
      "id": "3fb75293-1afd-4a75-bdfd-b27961cd127e",
      "lastReceipt": "{\"stack\":\"user2022-03-15T15:10:32.642Z<139029b5-4402-4c08-b41f-b7653e64cb93>d2cb5bf8-49ce-4d07-bbdc-aaa9418aae41\",\"ticket\":{\"id\":\"cb888fe2-a925-4571-9bc4-878ee585323b\",\"status\":\"ok\"}}",
      "lastReceiptCreated": "2022-04-10T11:00:23.093Z",
      "owner": "user",
      "updatedAt": "2022-04-10T11:00:23.093Z",
    },
  },
  "2022-04-1122b29a72-c30f-4a33-a164-0497b33122c0": Object {
    "2": Object {
      "PushToken": "ExponentPushToken[*********************]",
      "StackName": "Pasta",
      "StackSchedule": "{\"2 on, 1 off weekdays\":{\"dw\":[0,1,2,3],\"type\":\"DAY_WEEK\",\"startDate\":\"2022-03-13T11:00:00.000Z\"}}",       
      "StackScheduleName": "2 on, 1 off weekdays",
      "UserID": "user",
      "createdAt": "2022-04-11T11:00:22.341Z",
      "id": "ff0d4f69-2d6b-4db8-90f6-db68c642042c",
      "lastReceipt": "{\"stack\":\"user2022-03-15T15:10:32.642Z<139029b5-4402-4c08-b41f-b7653e64cb93>d2cb5bf8-49ce-4d07-bbdc-aaa9418aae41\",\"ticket\":{\"id\":\"dc451865-8b66-4088-93a5-8985d869eb1c\",\"status\":\"ok\"}}",
      "lastReceiptCreated": "2022-04-11T11:00:22.341Z",
      "owner": "user",
      "updatedAt": "2022-04-11T11:00:22.341Z",
    },
  },
  "2022-04-11cc0bdf71-c796-4252-b4aa-9f8ffd7e49a9": Object {
    "3": Object {
      "PushToken": "ExponentPushToken[*********************]",
      "StackName": "Every other skip 4pm",
      "StackSchedule": "{\"Every other day\":{\"skip_days\":2,\"type\":\"SKIP_DAYS\",\"startDate\":\"2022-04-11T19:46:34.080Z\"}}",
      "StackScheduleName": "Every other day",
      "UserID": "user",
      "createdAt": "2022-04-11T20:00:22.549Z",
      "id": "83cf53f2-9981-4eb1-bc8a-28e833de7e67",
      "lastReceipt": "{\"stack\":\"user2022-04-11T19:47:42.994Z<139029b5-4402-4c08-b41f-b7653e64cb93>907e97a3-a438-49e7-bf5f-71ef8b23e7c4\",\"ticket\":{\"id\":\"0a4aa2dd-acb9-4cd2-89f4-5dec0b82337c\",\"status\":\"ok\"}}",
      "lastReceiptCreated": "2022-04-11T20:00:22.549Z",
      "owner": "user",
      "updatedAt": "2022-04-11T20:00:22.549Z",
    },
  },
  "2022-04-11dbf1fc4b-ca38-4ac5-b660-7b10195fc891": Object {
    "1": Object {
      "PushToken": "ExponentPushToken[*********************]",
      "StackName": "Everydaytest",
      "StackSchedule": "{\"Everyday\":{\"dw\":[6,7,1,2,3,4,5],\"type\":\"DAY_WEEK\",\"startDate\":\"2022-04-09T15:00:00.000Z\"}}",
      "StackScheduleName": "Everyday",
      "UserID": "user",
      "createdAt": "2022-04-11T15:00:22.660Z",
      "id": "597233b0-7327-4b13-923c-b3b9073c6747",
      "lastReceipt": "{\"stack\":\"user2022-04-09T14:52:37.519Z<139029b5-4402-4c08-b41f-b7653e64cb93>ba7cb97d-d6db-4086-82dd-b6a8c79712e5\",\"ticket\":{\"id\":\"38eef4db-4914-4885-ae5e-7de509b7d424\",\"status\":\"ok\"}}",
      "lastReceiptCreated": "2022-04-11T15:00:22.660Z",
      "owner": "user",
      "updatedAt": "2022-04-11T15:00:22.660Z",
    },
  },
}

While my markedDates state looks like this:虽然我的markedDates state 看起来像这样:

Object {
  "2022-04-09": Object {
    "dotColor": "grey",
    "marked": true,
  },
  "2022-04-10": Object {
    "dotColor": "grey",
    "marked": true,
  },
  "2022-04-11": Object {
    "dotColor": "grey",
    "marked": true,
  },
}

Up to this point, everything works, but in the following code when I am handling the pressing of the day, and the subsequent opening of the modal, this is where the TypeError: undefined is not an object (evaluating 'item.createdAt') occurs:到目前为止,一切正常,但在下面的代码中,当我处理当天的压力以及随后打开模态时,这是TypeError: undefined is not an object (evaluating 'item.createdAt')发生:

CalendarCard.js (second half) CalendarCard.js (下半场)

// continuation of above code
...
    function findValueByPrefix(obj,string) {
        let items = [];
        for (let property in obj) {
            if (obj.hasOwnProperty(property) &&
                property.toString().startsWith(string)) {
                    items.push(obj[property]);
                };
        };
        return items;
    };

    const handleDayPress = (day) => {
        const openModalWithData = (dayNotifications) => {
            setDayNotificationItems(dayNotifications);
            showDayModal();            
        };

        const dayString = day.dateString;
        let dayNotifications = findValueByPrefix(notificationItems,dayString);
        openModalWithData(dayNotifications);
    };

    return (
        <Card>
            <Card.Title title='My History'/>
            <Calendar
                onMonthChange={month => handleMonthChange(month)}
                markedDates={markedDates}
                onDayPress={day => handleDayPress(day)}
            />
            <Card.Content/>
        </Card>
    );
};

export default CalendarCard;

In the above code, setDayNotificationItems and showDayModal are passed into CalendarCard from the parent component which can be seen here:在上面的代码中, setDayNotificationItemsshowDayModal从父组件传递到CalendarCard ,可以在这里看到:

TrackerScreen.js TrackerScreen.js

import React, { useState } from "react";
import { ScrollView, View } from "react-native";
import { Portal } from "react-native-paper";
import { SafeAreaView } from "react-native-safe-area-context";
import CalendarDayModal from "../components/modals/CalendarDayModal";
import CalendarCard from "../components/tracker/CalendarCard";

const TrackerScreen = () => {
    const [dayNotificationItems, setDayNotificationItems] = useState();
    const [dayModalVisible, setDayModalVisible] = useState(false);
    const showDayModal = () => setDayModalVisible(true);
    const hideDayModal = () => setDayModalVisible(false);

    return (
        <SafeAreaView>
            <Portal>
                <CalendarDayModal
                    dayModalVisible={dayModalVisible}
                    hideDayModal={hideDayModal}
                    dayNotificationItems={dayNotificationItems}
                />
            </Portal>
            <ScrollView>
                <View>
                    <CalendarCard
                        showDayModal={showDayModal}
                        setDayNotificationItems={setDayNotificationItems}
                    />
                </View>
            </ScrollView>
        </SafeAreaView>
    );
};

export default TrackerScreen;

From this, the data shown above is passed up from CalendarCard to TrackerScreen when a user presses the day.由此,当用户按下日期时,上面显示的数据从CalendarCard传递到TrackerScreen This then triggers the CalendarDayModal to become visible and render a few components shown here:然后,这会触发CalendarDayModal变得可见并呈现此处显示的几个组件:

CalendarDayModal.js CalendarDayModal.js

import React from "react";
import { View } from "react-native";
import { ScrollView } from "react-native-gesture-handler";
import { Caption, Headline, IconButton, Modal } from "react-native-paper";
import DayNotifications from "../tracker/DayNotifications";

const CalendarDayModal = (
    {
        dayModalVisible,
        hideDayModal,
        dayNotificationItems
    }) => {

    const RenderDayNotifications = () => {
        if (dayNotificationItems.length > 0) {
            return (
                <View style={{flexDirection:'column',paddingVertical:5}}>
                    <Headline>Tracked Stacks</Headline>
                    <Caption>The things you tracked this day</Caption>
                    <DayNotifications
                        dayNotificationItems={dayNotificationItems}
                    />
                </View>
            );
        } else return(<View></View>);
    };
    return (
        <Modal
            visible={dayModalVisible}
            onDismiss={hideDayModal}
            contentContainerStyle={{
                backgroundColor:'#D7FFFF',
                width:'100%',
                height: '100%',
                alignSelf:'center'
            }}
        >
            <IconButton
                icon='check'
                size={20}
                style={{paddingTop: 10,position:'absolute',right:0,top:0}}
                onPress={hideDayModal}
            />
            <ScrollView style={{width: '95%',alignSelf:'center'}}>
                <RenderDayNotifications/>
            </ScrollView>
        </Modal>
    );
};

export default CalendarDayModal;

Here we see the end component where the TypeError: undefined is not an object (evaluating 'item.createdAt') is manifesting itself, where the <DayNotifications/> component is attempting to consume the data defined above.在这里我们看到结束组件,其中TypeError: undefined is not an object (evaluating 'item.createdAt')正在显现,其中<DayNotifications/>组件正在尝试使用上面定义的数据。 However, I believe part of the issue may be with my approach to filtering my data to select the items which match the day object from onDayPress={day => handleDayPress(day)} in the CalendarCard component where I use this function:但是,我认为部分问题可能与我将数据过滤到 select 的方法有关,这些项目与我使用此 function 的CalendarCard组件中的onDayPress={day => handleDayPress(day)}匹配day object:

    function findValueByPrefix(obj,string) {
        let items = [];
        for (let property in obj) {
            if (obj.hasOwnProperty(property) &&
                property.toString().startsWith(string)) {
                    items.push(obj[property]);
                };
        };

        return items;
    };

    const handleDayPress = (day) => {

        const openModalWithData = (dayNotifications) => {            setDayNotificationItems(dayNotifications);
            showDayModal();            
        };

        const dayString = day.dateString;
        let dayNotifications = findValueByPrefix(notificationItems,dayString);

        openModalWithData(dayNotifications);
    };

Below is my DayNotifications component, where the error is happening:下面是我的DayNotifications组件,发生错误的地方:

DayNotifications.js DayNotifications.js

import React, { useState } from "react";
import 'react-native-get-random-values';
import { v4 as uuidv4 } from 'uuid';
import moment from 'moment';
import { View } from "react-native";
import { Caption, Card, Subheading, Text } from "react-native-paper";

const DayNotifications = ({dayNotificationItems}) => {
    const dayItems = [];
    Object.entries(dayNotificationItems).forEach(([k,v]) => dayItems.push(v[`${k}`]));

    const NotificationItemCard = ({item}) => {
        let deliveryDate = moment(item.createdAt).format('dddd, MMMM Do YYYY');
        // ^ ERROR TRIGGERED HERE
        let deliveryTime = moment(item.createdAt).format('h:mma');
        
        return(
            <Card>
                <Card.Title title={deliveryDate} subtitle={deliveryTime}/>
                <View style={{
                    flexDirection: 'column',
                    width: '90%',
                    alignSelf:'center',
                    paddingBottom: 5
                    }}
                >
                    <View style={{
                        flexDirection: 'col',
                        paddingVertical: 10
                        }}
                    >
                        <Subheading>{item.StackName}</Subheading>
                        <Caption>{item.StackScheduleName}</Caption>
                    </View>
                </View>
            </Card>
        );
    };
    return (
        <View style={{
            width: '95%',
            alignContent: 'center',
            alignSelf:'center'
            }}
        >
            {dayItems.map((item) =>
                <NotificationItemCard key={uuidv4()} item={item}/>
            )
            }
        </View>
    );
};

export default DayNotifications;

So, why is it that my calendar is rendering the dots, which the dat is derived from the createdAt field from the object resulting from the query, but after the transformations shown above, my DayNotifications component says that item.createdAt is undefined?那么,为什么我的日历正在呈现点,这些点是从查询产生的 object 的createdAt字段派生的,但是在上面显示的转换之后,我的DayNotifications组件说item.createdAt是未定义的? Is there an error with the way I'm passing down this data or is the error with the way I am storing the data or more likely is it an issue with the way I'm filtering the data before passing it to DayNotifications (which is what I think but have no idea what the issue is, yet)?我传递这些数据的方式是否有错误,或者我存储数据的方式是否有错误,或者更可能是我在将数据传递给DayNotifications之前过滤数据的方式有问题(这是我的想法是什么,但还不知道问题是什么)?

Solved, I was assuming that my findValueByPrefix was going to return consistent keys, but the establishment of the key value in some nested objects (purely for unique key values purposes) was not in fact establishing keys in any order.已解决,我假设我的findValueByPrefix将返回一致的键,但在某些嵌套对象中建立键值(纯粹为了唯一键值的目的)实际上并不是以任何顺序建立键。 Hence passing Object.entries(dayNotificationItems).forEach(([k,v]) => dayItems.push(v[ ${k} ]));因此传递Object.entries(dayNotificationItems).forEach(([k,v]) => dayItems.push(v[ ${k} ])); would try to reference the nested object by a key that was not present in the object (it may have been in some instances just by coincidence, which is why this error was infuriating).会尝试通过 object 中不存在的键来引用嵌套的 object(在某些情况下可能只是巧合,这就是为什么这个错误令人恼火)。

I elected to ignore the keys and just extract the values, since the keys were only there to ensure that objects which may be identical would not be overwritten or de-duped at any step.我选择忽略键并只提取值,因为键只是为了确保可能相同的对象在任何步骤都不会被覆盖或删除。 Here's all I had to do:这是我必须做的所有事情:

...
    const dayItems = [];
    Object.values(dayNotificationItems).forEach(item => {
        Object.values(item).forEach(v => {
            dayItems.push(v)
        });
    });
...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 react-native-calendars ExpandableCalendar 在本机反应中不能与 RTL 一起正常工作 - react-native-calendars ExpandableCalendar not worknig propely with RTL in react native 如何动态更改 react-native-calendars 的 items 道具中日期键的日期 - How to dynamically change the date for the date key in the items prop for react-native-calendars 如何向 react-native-calendars 中的 Agenda 组件添加功能 - How to add functionality to the Agenda component in react-native-calendars 需要帮助理解 react-native 语法 - Need help understanding react-native syntax react-native-calendars npm 模块的 CalendarList 组件中的日历天在正常模式下似乎被禁用/变灰,但在调试模式下工作正常 - Calendar days in CalendarList component of react-native-calendars npm module seems disabled/grayed out in normal mode but works fine in debug mode 使用 React-Native Navigation 传递数据 - Passing Data Using React-Native Navigation 需要帮助弄清楚 React 中的状态 - Need Help Figuring Out State in React React-Native 如何将我的 json 数据返回到我的道具? - React-Native how can i return my json data to my prop? React Native-使用prop的传递函数-作为prop - React Native - passing function that uses a prop, - as a prop 未设置本机亲本道具 - react-native parent prop not set
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM