i am trying to export a react native stack navigation but i am getting an error
*Warning: React.jsx: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: object.
*ERROR Warning: React.jsx: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: <ForwardRef(NavigationContainerInner) />. Did you accidentally export a JSX literal instead of a component?
Check the render method of 'TopsCloset'.
Stack navigation - File a
function TopsScreen ({navigation}) {
return(
<View>
<TouchableOpacity
onPress={() => navigation.navigate('TopsScreen')}
>
<Image
style= {liststyles2.listitems}
source={require('./images/tops.png')}
/>
</TouchableOpacity>
<Text style={liststyles2.listtext}>Tops</Text>
</View>
)
}
export {TopsScreen}
function TopsScreenCont ({navigation}) {
return(
<View>
<Text style={liststyles2.listtext}>Tops</Text>
</View>
)
}
export {TopsScreenCont}
const TopsNavStack = createStackNavigator();
function TopsScreenNav() {
return (
<TopsNavStack.Navigator>
<TopsNavStack.Screen name="TopsScreen" component={TopsScreen} />
<TopsNavStack.Screen name="TopsScreenCont" component={TopsScreenCont} />
</TopsNavStack.Navigator>
);
}
export {TopsScreenNav}
function TopsScreenExport() {
return(
<NavigationContainer independent = {true}>
<TopsNavStack />
</NavigationContainer>
);
}
export default TopsScreenExport();
Trying to import TopsScreenExport both with and without {}.
FIle b - trying to import the stack
import TopsScreenExport from './Tops'
const TopsCloset = () => {
return (
<View>
<TopsScreenExport />
</View>
);
}
I am trying to create just a simple stack navigation to work with touchable opacity. Note on the App file the i already call a bottomtabsnavigator which is working fine.
Well problem solved.
What i had wrong was the export default, indeed , and i had to import the second component
export function TopsScreenExport() {
return (
<NavigationContainer independent={true}>
<TopsNavStack />
</NavigationContainer>
);
}
And
export function TopsScreen({ navigation }) {
return (
<View>
<TouchableOpacity onPress={() => navigation.navigate('TopsScreen')}>
<Image style={liststyles2.listitems} source={require('./images/tops.png')} />
</TouchableOpacity>
<Text style={liststyles2.listtext}>Tops</Text>
</View>
);
}
And on the Myitems.js
import { TopsScreenExport, TopsScreen } from 'Tops.js'
Related
i am trying to learn react native but i faced with this 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 hace mixed up default and named imports.
Check the render method of 'GoalInput'(I am sure i didn't made a typo first'l' and after that 'i' letter)
my App.js code:
import { useState } from "react";
import { StyleSheet, View, FlatList, Button } from "react-native";
import { StatusBar } from "expo-status-bar";
import GoalItem from "./components/GoalItem";
import GoalInput from "./components/GoalInput";
return (
<>
<StatusBar/>
<View>
<Button onPress={startAddGoalHandler}/>
<GoalInput
visible={modalIsVisible}
onAddGoal={addGoalHandler}
onCancel={endAddGoalHandler}
/>
</View>
</>
);
my GoalInput.js code:
import { useState } from "react";
import { StyleSheet,Button,TextInput,View,Model,Image} from "react-native";
const GoalInput = (props) => {
const [enteredGoalText, setEnteredGoalText] = useState("");
const goalInputHandler = (enteredText) => {
setEnteredGoalText(enteredText);
};
const addGoalHandler = () => {
props.onAddGoal(enteredGoalText);
setEnteredGoalText("");
};
return (
<Model visible={props.visible} animationType="slide">
<View>
<Image
source={require("../assets/Images/goal.png")}
/>
<TextInput
onChangeText={goalInputHandler}
value={enteredGoalText}
/>
<View>
<View>
<Button title="Add Goal" onPress={addGoalHandler} color="#b180f0" />
</View>
<View>
<Button title="Cancel" onPress={props.onCancel} color="#f31282" />
</View>
</View>
</View>
</Model>
);
};
export default GoalInput;
I have deleted the style parts for keep question simple and even i search a lot couldn't find the error source on my own thanks for all the attention.
by the way i am using 'expo'
There's no Model in react native , its Modal
SO chnage this first :
import { StyleSheet,Button,TextInput,View,Modal,Image} from "react-native";
And also where youve used in
return(
<Modal>
</Modal>
)
Hope it helps. feel free for doubts
I'm trying to use useContext hook in a React Native page I have, I'm using this hook in other components as well and they work just fine, but this one won't - can't figure out why.
This is my component:
const GoalCard = (goal: IGoal) => {
const {theme} = useContext(ThemeContext); <-- error is here
return (
<Animated.View style={[styles.card, {height: cardHeight, backgroundColor: "#ff5e"}]}>
<View>
.....
</View>
</Animated.View>
);
I'm using this component inside a FlatList which is in a separate file.
return (
<SafeAreaView style={[styles.pageContainer, {backgroundColor: theme.background}]}>
<FlatList
showsVerticalScrollIndicator={false}
style={{padding: 8}}
data={goals}
renderItem={({index}) => GoalCard(goals[index])}
keyExtractor={item => item.id}
/>
</SafeAreaView>
);
I get the error: Invalid hook call, but it does not seem like something is wrong here.
Saw few questions about this, but none worked, also, nothing seems wrong according to the Rules of Hooks page. Why this error happens here?
EDIT:
this is my ThemeProvider:
function ThemeProvider({ children }) {
const [dark, setDark] = React.useState(false);
const toggle = () => {
setDark(!dark);
}
const theme = dark ? themes.dark : themes.light;
return (
<ThemeContext.Provider value={{theme, dark, toggle}}>
{children}
</ThemeContext.Provider>
)
}
And this is my App.tsx:
<ThemeProvider>
<Provider store={store}>
<NavigationContainer>
.....
</NavigationContainer>
</Provider>
</ThemeProvider>
I'm moving now from other technologies to React Native and I have a problem. I have one presentational component which is <TaskInput />.
const TaskInput = (props: ITaskInputProps) => {
return (
<View style={styles.container} >
<Text style={styles.title}>{props.title}</Text>
<TextInput
style={styles.input}
multiline
scrollEnabled={false}
/>
</View>
)
}
ParentComponent over TaskInput
import React from 'react';
import { View } from 'react-native';
import styles from './styles';
import TaskInputContainer from '../task-input';
interface ITaskConfigurationProps {
title: string,
isInputForm?: boolean,
isRequired?: boolean,
}
const TaskConfiguration = (props: ITaskConfigurationProps) => {
return (
<View style={(props.isRequired) ? [styles.container, {backgroundColor: '#f25e5e'}] : styles.container}>
{ props.isInputForm && <TaskInputContainer title={props.title} /> }
</View>
);
}
export default TaskConfiguration;
const TaskScreen = (props: ITaskScreenProps) => {
return (
<View style={styles.container}>
<SectionTitle title={'Task Settings'} />
<ScrollView contentContainerStyle={styles.configurations}>
<TaskConfiguration title={"What you need to do?"} isInputForm={true} isRequired={true} />
<TaskConfiguration title={"Description"} isInputForm={true} />
<TaskConfiguration title={"Deadline"} />
<TaskConfiguration title={"Priority"} />
</ScrollView>
<Button isDone={true} navigation={props.navigation} />
</View>
)
}
TaskInput component takes one prop which is title and it will be in two places on my screen. One component will be called "Enter main task", another one is "Description". But this component will accept different states like currentMainTextInput and currentDescriptionTextInput. This is my idea of re-usable component TextInput, but I can't do what I want because if I set type in one input - other input will re-render with first input (both of them are one presentational component).
I want to use this dumb component in any place of my app. I don't want to create a new identical component and duplicate code, How can I do that? (P.S. I was thinking about "redux or class/hooks", but what should I use...)
I am new to React Native and I have been building a simple Food Recipe app. My main Stack Navigator contains two screens: Bottom Tab Navigator and Recipe screen. I am in Home screen in the Tab Navigator and when I press any recipe, I want to pass recipe props and navigate to Recipe screen in the main Stack Navigator. Unfortunately, I haven't found any solution to this.
Could you please help me solve this?
This is the main file App.js
const Navigator = createBottomTabNavigator(
{
Home: Home,
Add: Add,
Profile: Profile
}
);
const Stack = createStackNavigator(
{
Navigator: Navigator,
Recipe: Recipe
},
{
headerMode: "none",
navigationOptions: {
headerVisible: false,
}
}
);
export default createAppContainer(Stack)
This is my Home Screen class
export default class Home extends Component {
render() {
return (
<SafeAreaView style={styles.container}>
<View style={styles.header}>
<Text style={styles.headerTitle}>Recipes</Text>
</View>
<ScrollView style={styles.categoryContainer}>
<Category name={"All Foods"} recipes={recipes} />
<Category name={"Meat"} recipes={[ recipes[1], recipes[3] ]} />
<Category name={"Vegetarian"} recipes={[ recipes[0], recipes[2] ]} />
<Category name={"Desserts"} recipes={[ recipes[4] ]} />
</ScrollView>
</SafeAreaView>
)
}
}
This is the Category class
export default class Category extends Component {
render() {
return (
<View style={styles.container}>
<View style={styles.categoryHeader}>
<Text style={styles.categoryHeaderTitle}>{this.props.name}</Text>
</View>
<ScrollView >
<View style={styles.categoryContent}>
<FlatList
data={this.props.recipes}
renderItem={({ item }) => <Block name={item.name} image={item.image} time={item.time} portions={item.portions} />}
keyExtractor={(item, index) => index.toString()}
horizontal={true}
/>
</View>
</ScrollView>
</View>
)
}
}
This is the actual recipe block where I want to navigate all the way back to the Recipe screen and pass recipe props using onPress={} function
export default class Block extends Component {
render() {
return (
<TouchableOpacity style={styles.container} onPress={null} >
<Image style={styles.image} source={this.props.image} />
<Text style={styles.title}>{this.props.name}</Text>
<Text style={styles.info}>{this.props.time} min | portions: {this.props.portions}</Text>
</TouchableOpacity>
)
}
}
Thank you for all your answers
If you need the StackNavigator to display a header on top of a BottomTabNavigator i would suggest to use a StackNavigator for every child of the bottomTabBar. Doing like that you can have more screens in a single tabBarItem, and you won't have the bottomTabBar disappearing for the other screens.
If you don't mind of this, you can access your stackNavigator from his child using dangerouslyGetParent and then navigate with the props you need.
navigateToRecipe = (recipe) => {
this.props.navigation.dangerouslyGetParent().navigate("Recipe", { recipe : myRecipe}) //pass an object with the data you need
}
Then you can access your recipe props either using getParam this.props.navigation.getParam("recipe") or directly using this.props.navigation.state.params
I'm currently creating a small example of React Native. The issue I'm having is that when I tried to pass the image source from my LoginScreen component to ImageHolder component, the Node shows error below:
Loading dependency graph, done.
error: bundling failed: Error: src\ImageHolder.js:Invalid call at line 7: require({
imageSource: imageSource
})
at C:\Users\Kuro\vuichoi_ui\node_modules\metro\src\JSTransformer\worker.js:247:19
at Generator.next (<anonymous>)
at step (C:\Users\Kuro\vuichoi_ui\node_modules\metro\src\JSTransformer\worker.js:40:30)
at C:\Users\Kuro\vuichoi_ui\node_modules\metro\src\JSTransformer\worker.js:51:15
Here is my code:
LoginScreen.js render:
render() {
if (true) {
return (
<View>
<LoginText
imgSource="./img/account.png"
secureOption={false}
value={this.state.username}
placeholder="username"
onChangeText={username => this.setState(username)}
/>
</View>
)
}
}
LoginText.js:
const LoginText = ({imgSource, secureOption, placeholder, value, onChangeText}) => {
return (
<View style={styles.containerStyle}>
<ImageHolder imageSource={imgSource} />
<InputField placeholder={placeholder} secureOption={secureOption} value={value} onChangeText={onChangeText}/>
</View>
)
}
ImageHolder.js:
const ImageHolder = ({imageSource}) => {
return (
<View style={styles.imgContainerStyle}>
<Image source={require(imageSource)}></Image>
</View>
)
}
The issue is in the path of Image. If all the component on the same path then you can the same thing.
The solutions is that you need to pass Image from LoginScreen.js
render() {
if (true) {
return (
<View>
<LoginText
imgSource={require('./img/account.png')}
secureOption={false}
value={this.state.username}
placeholder="username"
onChangeText={username => this.setState(username)}
/>
</View>
)
}
}
ImageHolder.js
const ImageHolder = ({imageSource}) => {
return (
<View style={styles.imgContainerStyle}>
<Image source={imageSource}></Image>
</View>
)
}
Replace the code above tow js and it will work for you.