Error When Attempting to Display Modal on 'Reserve' Click in React Native App

23 Views Asked by At

I'm encountering an issue while attempting to display a modal upon clicking the 'Reserve' button in my React Native app.

The error message "Uncaught Error: Element type is invalid" is shown, suggesting a problem with the usage of a component. I need help identifying and addressing the root cause of this issue. The provided code includes the main App component, RoomItem component, and the main entry point App.js. Further investigation is needed to resolve the error.

Error Message

Uncaught Error
Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
Check the render method of `App`.
Call Stack
createFiberFromTypeAndProps
node_modules/react-dom/cjs/react-dom.development.js
createFiberFromElement
node_modules/react-dom/cjs/react-dom.development.js
createChild
node_modules/react-dom/cjs/react-dom.development.js
reconcileChildrenArray
node_modules/react-dom/cjs/react-dom.development.js
reconcileChildFibers
node_modules/react-dom/cjs/react-dom.development.js
reconcileChildren
node_modules/react-dom/cjs/react-dom.development.js
updateHostComponent
node_modules/react-dom/cjs/react-dom.development.js
beginWork
node_modules/react-dom/cjs/react-dom.development.js
invokeGuardedCallbackDev
node_modules/react-dom/cjs/react-dom.development.js
invokeGuardedCallbackDev
node_modules/react-dom/cjs/react-dom.development.js
<anonymous>
node_modules/react-dom/cjs/react-dom.development.js
beginWork$1
http://localhost:8081/node_modules%5Cexpo-router%5Centry.bundle
performUnitOfWork
node_modules/react-dom/cjs/react-dom.development.js
workLoopSync
node_modules/react-dom/cjs/react-dom.development.js
renderRootSync
node_modules/react-dom/cjs/react-dom.development.js
performSyncWorkOnRoot
node_modules/react-dom/cjs/react-dom.development.js
flushSyncCallbacks
node_modules/react-dom/cjs/react-dom.development.js
ensureRootIsScheduled
node_modules/react-dom/cjs/react-dom.development.js
Collapse all 18 frames

app/index.js

import React, { useState } from "react";
import { View, StyleSheet, FlatList } from "react-native";
import { Title, Modal, Text, TextInput, Button, IconButton } from "react-native-paper";
import { Provider as PaperProvider } from "react-native-paper";
import DatePicker from "react-native-paper-dates"
import RoomItem from "./RoomItem";

const App = () => {
  const styles = StyleSheet.create({
    card: {
      flex: 1,
      margin: 8,
      elevation: 4,
    },
    cardImage: {
      height: 120,
      borderTopLeftRadius: 8,
      borderTopRightRadius: 8,
    },
    roomName: {
      fontSize: 16,
      fontWeight: "bold",
    },
    availableText: {
      color: "green",
      fontWeight: "bold",
    },
    notAvailableText: {
      color: "red",
      fontWeight: "bold",
    },
    cardActions: {
      justifyContent: "flex-end",
      paddingTop: 0,
      marginTop: 10,
    },
  });
  const [modalVisible, setModalVisible] = useState(false);
  const [selectedRoom, setSelectedRoom] = useState(null);
  const [selectedDate, setSelectedDate] = useState(null);
  const [reservationName, setReservationName] = useState("");
  const [reservationSurname, setReservationSurname] = useState("");

  const meetingRooms = [
    { id: 1, name: "Room 101", capacity: 10, isAvailable: true },
    { id: 2, name: "Room 102", capacity: 8, isAvailable: false },
    { id: 3, name: "Room 103", capacity: 12, isAvailable: true },
    { id: 4, name: "Room 104", capacity: 6, isAvailable: true },
    { id: 5, name: "Room 105", capacity: 4, isAvailable: false },
  ];

  const reserveRoom = (room) => {
    setSelectedRoom(room);
    setModalVisible(true);
  };

  const confirmReservation = () => {
    console.log(
      "Room reserved:",
      selectedRoom,
      "Date:",
      selectedDate,
      "Name:",
      reservationName,
      "Surname:",
      reservationSurname
    );
    setModalVisible(false);
  };

  return (
    <PaperProvider>
      <View style={styles.container}>
        <Title style={styles.title}>Room List</Title>
        <FlatList
          data={meetingRooms}
          keyExtractor={(item) => item.id.toString()}
          renderItem={({ item }) => <RoomItem room={item} reserveRoom={reserveRoom} />}
          numColumns={6} // Adjust the number of columns as needed
        />

        {/* Modal for Reservation */}
        <Modal visible={modalVisible} onDismiss={() => setModalVisible(false)}>
          <View style={styles.modalContainer}>
            <Text style={styles.modalTitle}>Reservation Details</Text>
            <DatePicker
              label="Date"
              value={selectedDate}
              mode="date"
              onChange={(date) => setSelectedDate(date)}
              style={styles.datePicker}
            />
            <TextInput
              label="Name"
              value={reservationName}
              onChangeText={(name) => setReservationName(name)}
              style={styles.input}
            />
            <TextInput
              label="Surname"
              value={reservationSurname}
              onChangeText={(surname) => setReservationSurname(surname)}
              style={styles.input}
            />
            <Button onPress={confirmReservation} mode="contained" style={styles.button}>
              Confirm Reservation
            </Button>
            <IconButton
              icon="close"
              onPress={() => setModalVisible(false)}
              style={styles.closeButton}
            />
          </View>
        </Modal>
      </View>
    </PaperProvider>
  );
};

export default App;

RoomItem.js

import React from "react";
import { StyleSheet } from "react-native";
import { Card, Title, Text, Button } from "react-native-paper";

const RoomItem = ({ room, reserveRoom }) => {
  const styles = StyleSheet.create({
    card: {
      flex: 1,
      margin: 8,
      elevation: 4,
    },
    cardImage: {
      height: 120,
      borderTopLeftRadius: 8,
      borderTopRightRadius: 8,
    },
    roomName: {
      fontSize: 16,
      fontWeight: "bold",
    },
    availableText: {
      color: "green",
      fontWeight: "bold",
    },
    notAvailableText: {
      color: "red",
      fontWeight: "bold",
    },
    cardActions: {
      justifyContent: "flex-end",
      paddingTop: 0,
      marginTop: 10,
    },
  });

  return (
    <Card style={styles.card}>
      {/* Assuming room.imageUrl is available in the room object */}
      <Card.Cover source={{ uri: room.imageUrl }} style={styles.cardImage} />
      <Title style={styles.roomName}>{room.name}</Title>
      <Text>Capacity: {room.capacity}</Text>
      <Text
        style={room.isAvailable ? styles.availableText : styles.notAvailableText}
      >
        {room.isAvailable ? "Available" : "Reserved"}
      </Text>
      <Card.Actions style ={styles.cardActions}>
        <Button onPress={() => reserveRoom(room)}>Reserve</Button>
      </Card.Actions>
    </Card>
  )
}
export default RoomItem;

App.js

import { StatusBar } from 'expo-status-bar';
import { Text, View } from 'react-native';

export default function MeetingRoomsApp() {
  return (
    <View>
      <Text>Open up App.js to start working on your app!</Text>
      <StatusBar/>
    </View>
  );
}
0

There are 0 best solutions below