I get this error Error: "HomeScreen" is read-only.
I was compiling and executing this expo app via expo-start and then pressing "i" for the IOS simulator. Then it gives me the following error:
Error: "HomeScreen" is read-only.
This error is located at:
in App (created by withDevTools(App))
in withDevTools(App)
in RCTView (created by View)
in View (created by AppContainer)
in RCTView (created by View)
in View (created by AppContainer)
in AppContainer
in main(RootComponent)
at node_modules/react-native/Libraries/Core/ExceptionsManager.js:95:17 in reportException
at node_modules/react-native/Libraries/Core/ExceptionsManager.js:141:19 in handleException
at node_modules/react-native/Libraries/Core/setUpErrorHandling.js:24:39 in handleError
at node_modules/expo/build/errors/ExpoErrorManager.js:25:19 in errorHandler
at node_modules/expo/build/errors/ExpoErrorManager.js:30:24 in \<anonymous\>
at node_modules/#react-native/polyfills/error-guard.js:49:36 in ErrorUtils.reportFatalError
I just don't get it, what does it mean "Read-only"? I have full permission on everything.
I was expecting a "Login Screen" message in the top-left of the screen, respecting the notch and that stuff.
This is my code for app.js:
import { StatusBar } from "expo-status-bar";
import { StyleSheet, Text, View } from "react-native";
import { NavigationContainer } from '#react-navigation/native';
import { createNativeStackNavigator } from '#react-navigation/native-stack';
import LoginScreen from "./screens/LoginScreen";
import HomeScreen from "./screens/HomeScreen";
const Stack = createNativeStackNavigator();
export default function App() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Home" component={HomeScreen={}} />
<Stack.Screen name="Login" component={LoginScreen={}} />
</Stack.Navigator>
</NavigationContainer>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#fff",
alignItems: "center",
justifyContent: "center",
},
});
This is for LoginScreen:
import { StyleSheet, Text, View } from 'react-native'
import React from 'react'
const LoginScreen = () => {
return (
<View>
<Text>LoginScreen</Text>
</View>
)
}
export default LoginScreen
const styles = StyleSheet.create({})
And this is for HomeScreen:
import { StyleSheet, Text, View } from 'react-native'
import React from 'react'
const HomeScreen = () => {
return (
<View>
<Text>HomeScreen</Text>
</View>
)
}
export default HomeScreen
const styles = StyleSheet.create({})
HomeScreen is a const which is read-only and can only be assigned a value once.
In your Stack.Screen you're setting the component prop to your custom components but assigning some value HomeScreen={}, same for LoginScreen
<Stack.Navigator>
<Stack.Screen name="Home" component={HomeScreen={}} />
<Stack.Screen name="Login" component={LoginScreen={}} />
</Stack.Navigator>
Instead use
<Stack.Navigator>
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Login" component={LoginScreen} />
</Stack.Navigator>
Related
I try to navigate between two pages in a React Native app. I keep getting errors for my implementations but I don't know why.
I have the following setup for a "Home" and "Settings" site in the React Native app with Navigator adjusted from the documentation:
App.js
import Home from "./Home";
import { NavigationContainer } from '#react-navigation/native';
export default function App() {
return <NavigationContainer><Home/></NavigationContainer>
}
Home.jsx
const Home = ({ navigation }) => {
return (
<View style={["some style...", {}]}>
<View style={["some style..."]}>
<TouchableOpacity onPress={() =>
navigation.navigate('Settings')}>
<Image "some image..."/>
</TouchableOpacity>
</View>
</View>
Settings.jsx
A component which should be rendered.
MyStack.jsx
import * as React from 'react';
import { NavigationContainer } from '#react-navigation/native';
import { createNativeStackNavigator } from '#react-navigation/native-stack';
import Home from './Home';
import Settings from './Settings';
const Stack = createNativeStackNavigator();
const MyStack = () => {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen
name="Home"
component={Home}
/>
<Stack.Screen name="Settings" component={Settings} />
</Stack.Navigator>
</NavigationContainer>
);
};
I get undefined is not an object (evaluating 'navigation.navigate'). Also adding this.props to navigation.navigate('Settings') throws and error. I am just not able to access my Navigator.
You seem to be setting up a navigator but never using it, since in App.js you are just calling <Home/>.
Change App.js to this:
import MyStack from "./MyStack"; // Use the correct path for the import
export default function App() {
return <MyStack/>
}
Add at the end of MyStack.jsx:
export default MyStack;
I was making an app with react native and react-navigation. So what I did was I made a Login screen. Then I used react-navigation to create a native stack navigator and linked it to my Login screen. I successfully rendered the Login Screen but there seems to be some sort of default styling on the stack navigator(?). How do I remove or overwrite those styles so that the original styling of my screens come back? Images and Code below.
This is the stack navigator
import React from 'react';
import { NavigationContainer } from '#react-navigation/native';
import { createNativeStackNavigator } from '#react-navigation/native-stack';
import LoginScreen from '../screens/LoginScreen';
import SignUpScreen from '../screens/SignUpScreen';
const Stack = createNativeStackNavigator();
const AuthStack = () => {
return (
<NavigationContainer>
<Stack.Navigator initialRouteName="Login" screenOptions={{ header: () => null }}>
<Stack.Screen name="Login" component={LoginScreen} />
<Stack.Screen name="Signup" component={SignUpScreen} />
</Stack.Navigator>
</NavigationContainer>
);
};
export default AuthStack;
When I only render the LoginScreen it looks like this
When I use AuthStack it looks like this
Should have read the docs nicely it was there in the NativeStackNavigator options.
import React from 'react';
import { NavigationContainer } from '#react-navigation/native';
import { createNativeStackNavigator } from '#react-navigation/native-stack';
import LoginScreen from '../screens/LoginScreen';
import SignUpScreen from '../screens/SignUpScreen';
const Stack = createNativeStackNavigator();
const AuthStack = () => {
return (
<NavigationContainer>
<Stack.Navigator
initialRouteName="Login"
screenOptions={{
headerShown: false,
header: () => null,
contentStyle: { backgroundColor: 'white' },
}}
>
<Stack.Screen name="Login" component={LoginScreen} />
<Stack.Screen name="Signup" component={SignUpScreen} />
</Stack.Navigator>
</NavigationContainer>
);
};
export default AuthStack;
To do your own style do this
import { createStackNavigator } from "#react-navigation/stack";
import { NavigationContainer, DefaultTheme } from "#reactnavigation/native";
const MyTheme = {
...DefaultTheme,
colors: {
...DefaultTheme.colors,
background: Color.red,
},
};
Then do this
<NavigationContainer theme={MyTheme}>
<Stack.Navigator initialRouteName="startscreen" headerMode="none" >
</Stack.Navigator>
</NavigationContainer>
More information here (https://reactnavigation.org/docs/themes/)
I tried to create bottom Navigation,
Following this link : https://reactnavigation.org/docs/tab-based-navigation/#customizing-the-appearance
and here is my code :
import React from "react";
import { createBottomTabNavigator } from "#react-navigation/bottom-tabs";
import Ionicons from "react-native-vector-icons";
// Screens
import Home from "./Home";
import Settings from "./Settings";
const Tab = createBottomTabNavigator();
function MainContainer({ navigation }) {
return (
<Tab.Navigator
screenOptions={({ route }) => ({
tabBarIcon: ({ focused, color, size }) => {
let iconName;
if (route.name === "Home") {
iconName = focused
? "ios-information-circle"
: "ios-information-circle-outline";
} else if (route.name === "Settings") {
iconName = focused ? "ios-list-box" : "ios-list";
}
return <Ionicons name={iconName} size={size} color={color} />;
},
tabBarActiveTintColor: "tomato",
tabBarInactiveTintColor: "gray",
})}
>
<Tab.Screen name="Home" component={Home} />
<Tab.Screen name="Settings" component={Settings} />
</Tab.Navigator>
);
}
export default MainContainer;
But I got this error :
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 `TabBarIcon`.
I found out the mistake,
on the
import Ionicons from "react-native-vector-icons"; it should have been import Ionicons from "react-native-vector-icons/Ionicons"
Solutions:
You need wrap your <Tab.Navigator> into root navigation container
Example:
You need to first install dependency of #react-navigation/native
import {NavigationContainer} from '#react-navigation/native';
import {createStackNavigator} from '#react-navigation/stack';
import {createBottomTabNavigator} from '#react-navigation/bottom-tabs';
const Stack = createStackNavigator();
const Tab = createBottomTabNavigator();
const MainContainer = () => {
return (
<NavigationContainer>
<Tab.Navigator />
<Stack.Navigator />
...other your navigation
</NavigationContainer>
);
};
You can checkout react-navigaiton https://reactnavigation.org/docs/getting-started/
Just wrape your <Tab.Navigator> in <NavigationContainer>
import React from "react";
import { NavigationContainer } from '#react-navigation/native'
//Reset Imports
const Routes = () => {
return (
<NavigationContainer>
<Tab.Navigator>
</Tab.Navigator>
</NavigationContainer>
)
}
export default Routes
I'm trying to render a full screen modal in React Native when an 'Account' button is clicked in the top left of the header but receive the error
Cannot read property navigate of undefined
Where am I going wrong with this?
AppNavigator.js file:
import React, {useState} from 'react';
import {
Button,
Image,
Modal,
Pressable,
Text,
TextInput,
TouchableOpacity,
View,
} from 'react-native';
import {NavigationContainer} from '#react-navigation/native';
import {createStackNavigator} from '#react-navigation/stack';
import {HomeScreen} from '../../features/reports/screens/HomeScreen';
import {RiskAssessmentListScreen} from '../../features/reports/screens/RiskAssessmentListScreen';
import {ModalScreen} from '../../features/reports/screens/ModalScreen'
const Stack = createStackNavigator();
const AppNavigator = ({navigation}) => {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen
name="GoPAD"
component={HomeScreen}
options={{
headerLeft: () => (
<Button
onPress={() => navigation.navigate('MyModal')}
title="Account"
/>
),
headerRight: () => (
<Image
style={{tintColor: 'blue'}}
source={require('../../../assets/img/refreshIcon.png')}
/>
),
}}
/>
<Stack.Screen name="MyModal" component={ModalScreen} />
<Stack.Screen
name="Fire Risk Assessment - Flats"
component={RiskAssessmentListScreen}
options={{headerBackTitle: 'Back'}}
/>
</Stack.Navigator>
</NavigationContainer>
);
};
export default AppNavigator;
And my ModalScreen.js file:
import React from 'react'
import {View, Text, Button} from 'react-native'
export const ModalScreen = ({navigation}) => {
return (
<View style={{flex: 1, alignItems: 'center', justifyContent: 'center'}}>
<Text style={{fontSize: 30}}>This is a modal!</Text>
<Button onPress={() => navigation.goBack()} title="Dismiss" />
</View>
);
}
The navigation prop is only available in the children of NavigationContainer.
What you are doing right now is you are accessing the navigation at the parent of NavigationContainer, so navigation is undefined.
There are a few ways to solve this:
Move NavigationContainer up to your App.js or index.js, depending on your app structure.
Pass a ref to NavigationContainer, and reference the ref for its methods, as shown in documentation.
My app is currently set up as follows, and I want to show the Hub screen when the user presses on Study:
App.js:
import React, { Component } from 'react';
...
import { View } from 'react-native'
import { Provider } from 'react-redux'
import { createStore, applyMiddleware } from 'redux'
import rootReducer from './redux/reducers'
import thunk from 'redux-thunk'
const store = createStore(rootReducer, applyMiddleware(thunk))
...
export class App extends Component {
...
render() {
return (
<Provider store={store}>
<NavigationContainer>
<Stack.Navigator initialRouteName="Main">
<Stack.Screen name="Main" component={MainScreen} options={{ headerShown: false }}/>
</Stack.Navigator>
</NavigationContainer>
</Provider>
)
}
}
export default App
Main:
import React, { Component } from 'react'
import { View } from 'react-native'
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons'
import { connect } from 'react-redux'
import { bindActionCreators } from 'redux'
import { fetchUser, clearData } from '../redux/actions/index'
import ProfileScreen from './main/Profile'
import HomeScreen from './main/Home'
import StudyScreen from './main/Study'
import TestScreen from './main/Test'
import { createMaterialBottomTabNavigator } from '#react-navigation/material-bottom-tabs'
const Tab = createMaterialBottomTabNavigator();
// https://reactnavigation.org/docs/bottom-tab-navigator/
export class Main extends Component {
componentDidMount() {
this.props.clearData();
this.props.fetchUser();
}
render() {
...
return (
<Tab.Navigator initialRouteName="Home" activeColor="#f0edf6" barStyle={{ backgroundColor: '#694fad' }} shifting='true'>
<Tab.Screen name="Home" component={HomeScreen}
options={{
tabBarLabel: 'Home', tabBarColor: '#FF6347', tabBarIcon: ({ color, size }) => (
<MaterialCommunityIcons name="home" color={color} size={26}/>
),
}} />
<Tab.Screen name="Study" component={StudyScreen}
options={{
tabBarLabel: 'Study', tabBarColor: '#694FAD', tabBarIcon: ({ color, size }) => (
<MaterialCommunityIcons name="school" color={color} size={26}/>
),
}} />
<Tab.Screen name="Profile" component={ProfileScreen}
options={{
tabBarLabel: 'Profile', tabBarColor: '#1F65FF', tabBarIcon: ({ color, size }) => (
<MaterialCommunityIcons name="account" color={color} size={26}/>
),
}} />
<Tab.Screen name="Test" component={TestScreen}
options={{
tabBarLabel: 'Test', tabBarColor: '#3490AA', tabBarIcon: ({ color, size }) => (
<MaterialCommunityIcons name="history" color={color} size={26}/>
),
}} />
</Tab.Navigator>
)
}
}
const mapStateToProps = (store) => ({
currentUser: store.userState.currentUser
})
const mapDispatchProps = (dispatch) => bindActionCreators({fetchUser, clearData}, dispatch)
export default connect(mapStateToProps, mapDispatchProps)(Main);
Study:
import React, { Component } from 'react'
import { NavigationContainer } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
const Stack = createStackNavigator();
import HubScreen from './studyWebviews/Hub'
export class Study extends Component {
render() {
return (
<NavigationContainer>
<Stack.Navigator initialRouteName="Hub">
<Stack.Screen name="Hub" component={HubScreen} options={{ headerShown: false }}/>
</Stack.Navigator>
</NavigationContainer>
);
}
}
Hub:
import React from 'react'
import { Text } from 'react-native'
export default function Hub() {
return (
<Text>Hub</Text>
)
}
Trying to load my app gives this error:
×
Error: Couldn't find a 'component', 'getComponent' or 'children' prop for the screen 'Study'. This can happen if you passed 'undefined'. You likely forgot to export your component from the file it's defined in, or mixed up default import and named import when importing.
How do I fix this? Please let me know if I need to clarify anything or make any changes for the sake of readability, thank you.
I believe you are importing the components incorrectly, as the message suggests: "...or mixed up default import and named import when importing."
Try export default class Study...