Snack.expo Attempted to assign to readonly property #react-navigation/native - javascript

Link: snack
It is based on an example of the component: react-native-animated-tabbar.
But it seems that the problem is on the module #react-navigation/native, which on snack.expo does not seem to work properly, giving me the following error:
Device: (857:881) Attempted to assign to readonly property.
Evaluating module://#react-navigation/native.js
Evaluating module://App.tsx.js
Loading module://App.tsx
App.tsx:
import React from 'react';
import 'react-native-gesture-handler';
import { NavigationContainer } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
import RootScreen from './screens/Root';
import BubbleScreen from './screens/Bubble';
import BubbleStyledScreen from './screens/BubbleStyled';
import BubbleRTLScreen from './screens/BubbleRTL';
const Stack = createStackNavigator();
export default function App() {
return (
<NavigationContainer>
<Stack.Navigator initialRouteName="Root" headerMode="none">
<Stack.Screen name="Root" component={RootScreen} />
<Stack.Screen name="Bubble" component={BubbleScreen} />
<Stack.Screen name="BubbleStyled" component={BubbleStyledScreen} />
<Stack.Screen name="BubbleRTL" component={BubbleRTLScreen} />
</Stack.Navigator>
</NavigationContainer>
);
}

Related

React-Native Error: Element type is invalid(). Check the render method of `Details`

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 Details.
Below i am attaching the code.I have double checked everything still it is giving error.I dont know what is the problem in rendering Details.js
This is App.js code.
import * as React from 'react';
import { NavigationContainer } from '#react-navigation/native';
import { createNativeStackNavigator } from '#react-navigation/native-stack';
import HomeScreen from './Home';
import DashboardScreen from './Dashboard'
import DetailsScreen from './Details';
const Stack = createNativeStackNavigator();
const MyStack = () => {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Details" component={DetailsScreen}/>
<Stack.Screen
name="Home"
component={HomeScreen}
options={{ title: 'Welcome' }}
/>
<Stack.Screen name="Dashboard" component={DashboardScreen} />
</Stack.Navigator>
</NavigationContainer>
);
};
export default MyStack
This is Details.js code below.
import React from "react";
import { Text,View} from "react-native-paper";
const Details = () => {
return(
<View style = {{flex: 1,justifyContent:'center',alignItems:'center'}}>
<Text>
Enter Details Here
</Text>
</View>
)
}
export default Details;
In your Details.js change
import { Text,View} from "react-native-paper";
to
import { Text, View} from "react-native";

How to remove default styles from react-navigation?

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/)

Pass props from App class to const function React Typescript

Im trying to create an React Native App with Expo.
I have a logical error passing props from App class to my Component "Navigator" type const function.
Im not sure how i must to pass the props or how i must to access to them without passing from App:
App.tsx
import React, {useState} from 'react';
import { NavigationContainer, StackActions } from '#react-navigation/native';
import Navigator from './Components/Navigator';
export default class App extends React.Component {
render(){
return (
<NavigationContainer>
<Navigator props={this.props}/>
</NavigationContainer>
);
}
}
Navigator.tsx
import React from 'react'
import { createStackNavigator } from '#react-navigation/stack'
import Login from '../Views/Login'
import Home from '../Views/Home'
const Stack = createStackNavigator();
function Navigator({props}){
return (
<Stack.Navigator>
<Stack.Screen name="Login" options={{title:'Login.'}}>
{(props) => <Login {...props} />}
</Stack.Screen>
<Stack.Screen name="Home" component={Home} options={{title:'Home.'}}/>
</Stack.Navigator>
);
}
export default Navigator;
I have error undefined is not an object (props)
This happens because you are make destructuring
Then when you call props it's like doing props.props
function Navigator(props){// remove { } from this line

React Native firebase Authentication handling

I am trying to create a simple Auth flow in my Expo application.
I've reacreated my project here so you can see what I am doing
Right now what happens in my app is I can register a user using Firebase authtentication, but can't navigate to the authenticated flows. Nothing happens after I click register, but I can see the user in firebase.
I have been reading the React Navigaion docs and tried implementing something similar to what they do for the Auth flow there, but have not had any success.
I think the issue has to do with how I am getting the token in App.js and my use of useEffect
App.js
import React, { useEffect } from 'react';
import * as eva from '#eva-design/eva';
import { Provider as AuthProvider } from './src/context/AuthContext';
import { createDrawerNavigator } from '#react-navigation/drawer';
import { createStackNavigator } from '#react-navigation/stack';
import { ApplicationProvider } from '#ui-kitten/components';
import { NavigationContainer } from '#react-navigation/native';
import LandingScreen from './src/screens/LandingScreen';
import RegisterScreen from './src/screens/RegisterScreen';
import LoginScreen from './src/screens/LoginScreen';
import HomeScreen from './src/screens/HomeScreen';
import DetailScreen from './src/screens/DetailScreen';
const Drawer = createDrawerNavigator();
const Stack = createStackNavigator();
/*eslint-disable */
export default function App() {
let token;
useEffect(() => {
// Fetch the token from storage then navigate to our appropriate place
const localSignin = async () => {
try {
token = await AsyncStorage.getItem('userToken');
} catch (e) {
// Restoring token failed
}
};
console.log(token);
localSignin();
}, []);
return (
<ApplicationProvider {...eva} theme={eva.light}>
<AuthProvider>
<NavigationContainer>
{token ? (
<>
<Drawer.Navigator initialRouteName="Home">
<Drawer.Screen name="Home" component={HomeScreen} />
<Drawer.Screen name="Details" component={DetailScreen} />
</Drawer.Navigator>
</>
) : (
<>
<Stack.Navigator>
<Stack.Screen name="Landing" component={LandingScreen} />
<Stack.Screen name="Register" component={RegisterScreen} />
<Stack.Screen name="Login" component={LoginScreen} />
</Stack.Navigator>
</>
)}
</NavigationContainer>
</AuthProvider>
</ApplicationProvider>
);
}
Should I be using my AuthContext here somewhere? I am very new to react development so I am sorry if this is somewhat unclear.
Your "token" is manipulated asynchronously, so it should be a state variable so your component may re-render when it got changed. To achieve that, you should replace your token declaration with
const [token, setToken] = React.useState(undefined);
After that, when you want to change your token, instead of reassigning to the token variable, call setToken with the desired value. Like this:
setToken(await AsyncStorage.getItem('userToken'));
The final code should look like this
import React, { useEffect } from 'react';
import * as eva from '#eva-design/eva';
import { Provider as AuthProvider } from './src/context/AuthContext';
import { createDrawerNavigator } from '#react-navigation/drawer';
import { createStackNavigator } from '#react-navigation/stack';
import { ApplicationProvider } from '#ui-kitten/components';
import { NavigationContainer } from '#react-navigation/native';
import LandingScreen from './src/screens/LandingScreen';
import RegisterScreen from './src/screens/RegisterScreen';
import LoginScreen from './src/screens/LoginScreen';
import HomeScreen from './src/screens/HomeScreen';
import DetailScreen from './src/screens/DetailScreen';
const Drawer = createDrawerNavigator();
const Stack = createStackNavigator();
/*eslint-disable */
export default function App() {
const [token, setToken] = React.useState(undefined);
useEffect(() => {
// Fetch the token from storage then navigate to our appropriate place
const localSignin = async () => {
try {
setToken(await AsyncStorage.getItem('userToken'));
} catch (e) {
// Restoring token failed
}
};
console.log(token);
localSignin();
}, []);
return (
<ApplicationProvider {...eva} theme={eva.light}>
<AuthProvider>
<NavigationContainer>
{token ? (
<>
<Drawer.Navigator initialRouteName="Home">
<Drawer.Screen name="Home" component={HomeScreen} />
<Drawer.Screen name="Details" component={DetailScreen} />
</Drawer.Navigator>
</>
) : (
<>
<Stack.Navigator>
<Stack.Screen name="Landing" component={LandingScreen} />
<Stack.Screen name="Register" component={RegisterScreen} />
<Stack.Screen name="Login" component={LoginScreen} />
</Stack.Navigator>
</>
)}
</NavigationContainer>
</AuthProvider>
</ApplicationProvider>
);
}

Error: Looks like you have nested a 'NavigationContainer' inside another. Normally you need only one container at the root of the app

I followed the docs of React 5 for Drawer Navigation in react native but getting this error. Here is my Code
import React from 'react'
import {
View,
Button,
Text,
} from 'react-native'
import { createDrawerNavigator } from '#react-navigation/drawer';
import { NavigationContainer } from '#react-navigation/native';
import Screen1 from './DrawerScreens/Screen1';
import Screen2 from './DrawerScreens/Screen2';
import Screen3 from './DrawerScreens/Screen3';
const Drawer = createDrawerNavigator();
function Navigations()
{
return(
<NavigationContainer>
<Drawer.Navigator initialRouteName="Home">
<Drawer.Screen name="Home" component={Screen1} />
<Drawer.Screen name="Settings" component={Screen2} />
<Drawer.Screen name="Contacts" component={Screen3} />
</Drawer.Navigator>
</NavigationContainer>
);
}
export default Navigations;
I am new to react native, so don't know what to do
You only need to declare one < NavigationContainer > in the top component, example:
function SecondComponent() {
return (
<Tab.Navigator>
<Tab.Screen name="Feed" component={Feed} />
<Tab.Screen name="Messages" component={Messages} />
</Tab.Navigator>
);
}
function FirstComponent() {
return (
<NavigationContainer> {/* this is the only NavigationContainer */}
<Stack.Navigator>
<Stack.Screen name="Home" component={Home} />
<Stack.Screen name="Profile" component={Profile} />
<Stack.Screen name="Settings" component={Settings} />
</Stack.Navigator>
</NavigationContainer>
);
}
pass independent={true} to both of the Navigation container .
<NavigationContainer independent={true}>
</NavigationContainer>
But you will not be able to navigate between the screens of two separate navigation container
If you want to navigate between them then you have to maintain single navigation container.
If you have only one NavigationContainer in your app, please check if you're importing screens correctly.
In my case, I've mistakenly imported the entry route file which contains NavigationContainer itself.
This can happen if you're using same file names for entry route files (e.g. Root.tsx or Main.tsx) and let IDE import files automatically.
You should have only one NavigationContainer in your whole application and it should be in the root level, which is the App class. So here you can see two different components, Navigation and App.
In Navigation component, Drawer Navigator helps to navigate different screens. Import this Navigation component in App component and wrap this with NavigationContainer.
// **** Navigation component ****
import React from 'react';
import {
View,
Button,
Text,
} from 'react-native';
import { createDrawerNavigator } from '#react-navigation/drawer';
import Screen1 from './DrawerScreens/Screen1';
import Screen2 from './DrawerScreens/Screen2';
import Screen3 from './DrawerScreens/Screen3';
const Drawer = createDrawerNavigator();
function Navigation() {
return (
<Drawer.Navigator initialRouteName="Home">
<Drawer.Screen name="Home" component={Screen1} />
<Drawer.Screen name="Settings" component={Screen2} />
<Drawer.Screen name="Contacts" component={Screen3} />
</Drawer.Navigator>
);
}
export default Navigation;
// **** App component ****
import React from 'react';
import { NavigationContainer } from '#react-navigation/native';
import {Navigation} from './Navigation';
function App() {
return (
<NavigationContainer>
<Navigation />
</NavigationContainer>
);
}
export default App;
I faced similar type of error while using Stack Navigator and this approach works for me.
In my case I have used BOTTOM NAVIGATION so it has that <NavigationContainer>
just removing <NavigationContainer> in BOTTOM NAVIGATION and only keeping it between <Stack.Navigator> resolved my problem
I think this will helpful for someone ✌

Categories

Resources