Error: Element type is invalid when creating Input in Component

Viewed 161

I have created a sub component for updating values of recipes I fetch from API. However when I do so I get:

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 `UpdateCourse`.

Navigator to the Update function component:

<Button
              title="UPDATE RECIPE"
              style={Styles.searchBtn}
              onPress={() =>
                navigation.navigate("Update_course", {
                  id: "60c9a32cb076563888b5782a",
                })
              }
            />
          </View>

Update Component:

    import React, { useState, useEffect } from "react";
import { Button, Image, TextInput, Text, Linking, View } from "react-native";
import Styles from "../../styles/Styles";
import Alert from "../elements/Alert";
import Axios from "axios";
import APIRequest from "../elements/APIRequest";

export default function UpdateCourse(id) {
  const [dishName, setdishName] = useState("");
  const [category, setcategory] = useState("");
  const [author, setauthor] = useState("");
  const [ingredients, setingredients] = useState([]);
  const [cookingTime, setcookingTime] = useState("");
  const [sourceUrl, setsourceUrl] = useState("");
  const [imageUrl, setimageUrl] = useState("");
  const [isPublished, setisPublished] = useState("true");
  const [price, setprice] = useState("");
  const [tags, settags] = useState([]);
  const [alert, setAlert] = useState("");

  const url = `http://x.x.x.x:1234/api/courses/find/${id}`;

  useEffect(() => {
    async function getData() {
      const result = await Axios.get(url);
      setdishName(result.data.dishName);
      setcategory(result.data.category);
      setauthor(result.data.author);
      setingredients(result.data.ingredients);
      setcookingTime(result.data.cookingTime);
      setsourceUrl(result.data.sourceUrl);
      setimageUrl(result.data.imageUrl);
      setisPublished(result.data.isPublished);
      setprice(result.data.price);
      settags(result.data.tags);
    }
    getData();
  }, [url]);

  async function update() {
    let item = {
      dishName,
      category,
      author,
      ingredients,
      cookingTime,
      sourceUrl,
      imageUrl,
      isPublished,
      price,
      tags,
    };

    const result = await APIRequest(
      `http://x.x.x.x:1234/api/courses/${id}`,
      "PUT",
      JSON.stringify(item)
    );

    if (result.status !== 200) {
      return setAlert(
        result.status +
          " " +
          result.statusText +
          " - Please check TextInput fields"
      );
    }
  }

  const handleIngredientsChange = (event, index) => {
    const shallowCopy = [...ingredients];
    shallowCopy[index] = {
      ...shallowCopy[index],
      [event.target.id]: event,
    };
    setingredients(shallowCopy);
  };

  return (
    <View style={{ minWidth: 70 }}>
      <View style={(Styles.bigBar, { textAlign: "center" })}>
        <Text> Update recipe</Text>
      </View>
      <View
        style={{
          backgroundColor: "#f1f1f1",
          padding: 3,
          borderRadius: 1,
          marginBottom: 7,
        }}
      >
        <View style={{}}>
          {alert !== "" && (
            <View style={{ display: "flex", justifyContent: "center" }}>
              <Alert alert={alert}></Alert>
            </View>
          )}
          <View>
            <Text>Name of the course</Text>
            <TextInput
              style={Styles.formControl}
              value={dishName}
              onChangeText={e => setdishName(e)}
            />
          </View>

          <View>
            <Text>Category</Text>
            <TextInput
              style={Styles.formControl}
              value={category}
              onChangeText={e => setcategory(e)}
            />
          </View>

          <View>
            <Text>Author</Text>
            <TextInput
              onChangeText={e => setauthor(e)}
              style={Styles.formControl}
              value={author}
            />
          </View>

          <View style={{ marginBottom: 2 }}>
            <Text>Ingredients</Text>
          </View>

          {ingredients.map(({ quantity, unit, description }, index) => {
            return (
              <View style="ing" key={"key" + index}>
                <Text>Quantity </Text>

                <TextInput
                  key={"quantity" + index}
                  style={
                    (Styles.formControl,
                    {
                      marginLeft: 1,
                      marginRight: 1,
                      width: 5,
                    })
                  }
                  onChangeText={event => handleIngredientsChange(event, index)}
                  value={quantity}
                />
                <View style={{ marginRight: 2 }}> Unit </View>
                <View>
                  <TextInput
                    key={"unit" + index}
                    style={(Styles.formControl, { width: 5 })}
                    onChangeText={event =>
                      handleIngredientsChange(event, index)
                    }
                    value={unit}
                  />
                </View>
                <View style={{ marginLeft: 1 }}>
                  {" "}
                  <Text>Description</Text>{" "}
                </View>

                <TextInput
                  key={"description" + index}
                  style={(Styles.formControl, { marginLeft: 1 })}
                  onChangeText={event => handleIngredientsChange(event, index)}
                  value={description}
                />
              </View>
            );
          })}

          <View>
            <Text>Cooking time</Text>
            <TextInput
              onChangeText={e => setcookingTime(e)}
              style={Styles.formControl}
              value={cookingTime}
            />
          </View>

          <View>
            <Text>Source url</Text>
            <TextInput
              onChangeText={e => setsourceUrl(e)}
              style={Styles.formControl}
              value={sourceUrl}
            />
          </View>

          <View>
            <Text>Image url</Text>
            <TextInput
              onChangeText={e => setimageUrl(e)}
              style={Styles.formControl}
              value={imageUrl}
            />
          </View>

          <View>
            <Text>Publish state</Text>
            <TextInput
              onChangeText={e => setisPublished(e)}
              style={Styles.formControl}
              placeholder={"default: true"}
            />
          </View>

          <View>
            <Text>Price</Text>
            <TextInput
              onChangeText={e => setprice(e)}
              style={Styles.formControl}
              value={price}
            />
          </View>

          <View>
            <Text>Tags</Text>
            <TextInput
              onChangeText={e => settags(e)}
              style={Styles.formControl}
              value={tags}
            />
          </View>

          <View style={(Styles.prettyB, { textAlign: "center" })}>
            <Button onPress={update} title="Submit"></Button>
          </View>
        </View>
      </View>
    </View>
  );
}

Sample data:

{"isPublished":true,"tags":["pizza","greek"],"_id":"60c9e360b076563888b578a2","dishName":"Greek pizza","category":"pizza","author":"Paolo","ingredients":[{"_id":"60c9e360b076563888b578a3","quantity":0.75,"unit":"cup","description":"warm water"},{"_id":"60c9e360b076563888b578a4","quantity":0.5,"unit":"cup","description":"bread flour"},{"_id":"60c9e360b076563888b578a5","quantity":1.5,"unit":"tea spoon","description":"sea salt"},{"_id":"60c9e360b076563888b578a6","quantity":1,"unit":"cup","description":"baby arugula"},{"_id":"60c9e360b076563888b578a7","quantity":0.67,"unit":"cup","description":"grape tomatoes halved"},{"_id":"60c9e360b076563888b578a8","quantity":1,"unit":"drizzle","description":"olive oil"},{"_id":"60c9e360b076563888b578a9","quantity":1.5,"unit":"tea spoon","description":"dry active yeast"},{"_id":"60c9e360b076563888b578aa","quantity":2,"unit":"tea spoon","description":"sugar"},{"_id":"60c9e360b076563888b578ab","quantity":1,"unit":"lb","description":"hummus any variety"},{"_id":"60c9e360b076563888b578ac","quantity":0.67,"unit":"cup","description":"good pitted greek olives"},{"_id":"60c9e360b076563888b578ad","quantity":0.25,"unit":"cup","description":"crumbled feta cheese"}],"cookingTime":75,"sourceUrl":"https://www.crete.pl/kuchnia-grecka-dania-glowne-wegetarianskie/grecka-pizza-z-feta.html","imageUrl":"https://www.crete.pl/zdjecia/grecka-pizza-z-feta/pizza1.jpg","price":35.99,"date":"2021-06-16T11:41:20.508Z","__v":0}

However it does work fine when I use . It then displays text I created. I do not understand why I cannot put Input tags on this subpage however. Thank you for all help!

1 Answers

You have to use the TextInput , there is no component with the name InputText or Input

https://reactnative.dev/docs/textinput

<Input style={Styles.searchInput} onChangeText={onChange} value={query} />

Should be

<TextInput style={Styles.searchInput} onChangeText={onChange} value={query} />
Related