Component not updating/rerendering when redux toolkit state changes - reactjs

I'm using redux toolkit to manage state and am finding that the components are not updating when changes are made to the state.
I do see though, that when I listen to changes in my redux state within a useEffect that it will trigger the callback, meaning it is aware that the redux state has changed but the component is not rerendering.
Reading other questions it seems like a lot of the issues were about mutating the state, but I do know that using redux tool kit allows you to write "mutable" code and this is handled by Immer. Not sure if this is an issue that applies here...
My Slice:
const initialState = {
watchlists: []
}
export const watchlistsSlice = createSlice({
name: 'watchlists',
initialState,
reducers: {
updateWatchlists: (state, { payload }) => {
state.watchlists = payload;
},
},
})
export const { updateWatchlists } = watchlistsSlice.actions;
export default watchlistsSlice.reducer;
This is the component that calls the function that changes the state:
import React from 'react';
import { StyleSheet, View, Image } from 'react-native';
import { useSelector, useDispatch } from 'react-redux';
import Text from '../core/Text';
import Pressable from '../core/Pressable';
import { AddIcon } from '../core/Icons';
import { formatPrice, formatPercent } from '../../utils/formatNumber';
import { shortenLongText } from '../../utils/formatText';
import { updateWatchlists } from '../../redux/watchlistsSlice';
import { addToWatchlist } from '../../storage/watchlists';
export default function ListItem({data, theme, navigation, watchlistID }) {
const dispatch = useDispatch();
const { currency } = useSelector(state => state.userPreference)
const addCryptoToWatchlist = async () => {
if (watchlistID) {
addToWatchlist(watchlistID, {
slug: data.slug,
})
.then(result => dispatch(updateWatchlists(result)))
.catch(err => console.log(err))
} else {
console.log('not ready yet')
}
}
return (
<Pressable
onPress={() => navigation.navigate('CoinDetails', {
data,
})}
>
<View style={styles.searchResult}>
<View style={styles.nameContainer}>
<Image style={styles.image} source={{uri: data.logo}} />
<View style={{marginLeft: 15}}>
<Text type={"big"} size={18} theme={theme.text}>{data.symbol}</Text>
<Text type={"regular"} size={14} theme={theme.text} style={{paddingTop: 1}}>{shortenLongText(data.name,25)}</Text>
</View>
</View>
<View style={styles.rightContainer}>
<View style={styles.priceContainer}>
<Text type={"big"} theme={theme.text}>{formatPrice(data.price, currency)}</Text>
<Text type={"big"} theme={data.direction === 'up' ? theme.percent.up : theme.percent.down}>{formatPercent(data.percent_change_24h)}</Text>
</View>
<Pressable onPress={() => addCryptoToWatchlist()}>
<AddIcon
size={30}
/>
</Pressable>
</View>
</View>
</Pressable>
)
}
const styles = StyleSheet.create({
searchResult: {
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
marginBottom: 30,
},
nameContainer : {
flexDirection: 'row',
alignItems: 'center',
},
rightContainer: {
flexDirection: 'row',
alignItems: 'center',
},
priceContainer: {
alignItems: 'flex-end',
marginRight: 20
},
image: {
width: 28,
height: 28,
}
})
This is one the components that I expect to rerender when the state changes:
The useEffect does get trigged so the component is recognizing a change in state, but the component does not rerender.
I dont know if this is insightful, but the data in the state is an array of objects and in this case a single property one of the objects is getting changed.
import React, { useState, useEffect } from 'react';
import { View, StyleSheet } from 'react-native';
import { useSelector } from 'react-redux';
import GetStarted from './GetStarted';
import AddCryptoCard from './AddCryptoCard';
import CardList from './CardList';
import Text from '../core/Text';
export default function WatchlistCardsSection({ setModalVisible, navigation }) {
const { theme } = useSelector(state => state.userPreference);
const { watchlists } = useSelector(state => state.watchlists)
const { cryptoData } = useSelector(state => state.cryptoData);
const [ watchlistCryptoDataLoaded, setWatchlistCryptoDataLoaded ] = useState(false);
const checkIfWatchlistDataLoaded = () => {
const watchlistNames = watchlists.map(watchlist => watchlist.name);
const checkIfLoaded = cryptoData.map(data => watchlistNames.some(name => data.tags.includes(name))).includes(true);
setWatchlistCryptoDataLoaded(checkIfLoaded);
}
useEffect(() => {
checkIfWatchlistDataLoaded();
},[cryptoData])
useEffect(() => console.log("watchlist updated"), [watchlists])
return (
watchlists &&
watchlists.length === 0 ?
<GetStarted
setModalVisible={setModalVisible}
/>
:
watchlists.filter(item => item.viewOnHome).map(watchlist => (
watchlist.data.length === 0 ?
<AddCryptoCard
key={watchlist.id}
id={watchlist.id}
name={watchlist.name}
navigation={navigation}
/>
:
watchlistCryptoDataLoaded ?
<View
key={watchlist.id}
style={styles.sectionContainer}
>
<Text style={{paddingLeft: 20}} type={'big'} size={24} theme={theme.text}>{watchlist.name}</Text>
<CardList
name={watchlist.name}
config={{type: 'price'}}
navigation={navigation}
/>
</View>
: null
))
)
}
const styles = StyleSheet.create({
sectionContainer: {
flex: 1,
marginTop: 25,
}
})

Related

TypeError: text.toLowerCase is not a function. (In 'text.toLowerCase()', 'text.toLowerCase' is undefined)

I am doing a project using MERN STACK in this I faced the above error.
ProductContainer.js
import React, { useState, useEffect } from 'react'
import { View, StyleSheet, ActivityIndicator, FlatList, Text} from 'react-native'
import { Container, Header, Icon, Item, Input } from 'native-base';
import ProductList from './ProductList';
import SearchedProduct from './SearchedProducts';
const data = require('../../assets/data/products.json');
const ProductContainer = () => {
const [products, setProducts ] = useState([]);
const [productsFiltered, setProductsFiltered] = useState([]);
const [focus, setFocus] = useState();
useEffect(() => {
setProducts(data);
setProductsFiltered(data);
setFocus(false);
return () => {
setProducts([])
setProductsFiltered([])
setFocus()
}
}, [])
const SearchProduct = (text) => {
setProductsFiltered(
products.filter((i) => i.name.toLowerCase().includes(text.toLowerCase()))
);
};
const openList = () => {
setFocus(true);
};
const onBlur = () => {
setFocus(flase);
};
return (
<Container>
<View style = {{ flexDirection: "row"}}>
<Input
width = "100%"
variant = "rounded"
placeholder="Search"
onFocus={openList}
onChangeText={(text) => SearchProduct(text)}
/>
</View>
{focus == true ? (
<SearchProduct
productsFiltered={productsFiltered}
/>
) : (
<View style={styles.container}>
<Text>Product Container</Text>
<View style={styles.listContainer}>
<FlatList
data={products}
numColumns={2}
renderItem={({item}) => <ProductList
key={item.brand}
item={item}/>}
keyExtractor={item => item.brand}
/>
</View>
</View>
)}
</Container>
)
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
export default ProductContainer
SearchedProducts.js
import React from 'react';
import { View, StyleSheet, Dimensions} from 'react-native'
import { Content, Left, Body, ListItem, Thumbnail, Text } from 'native-base';
const SearchedProduct = (props) => {
const { productsFiltered } = props;
return(
<Content >
{productsFiltered.length > 0 ? (
productsFiltered.map((item) => (
<ListItem
key={item._id.$oid}
avatar
>
<Left>
<Thumbnail
source={{uri: item.image ?
item.image : 'https://cdn.pixabay.com/photo/2012/04/01/17/29/box-23649_960_720.png'
}}
/>
</Left>
<Body>
<Text>{item.name}</Text>
<Text note>{item.description}</Text>
</Body>
</ListItem>
))
) : (
<View style={styles.center}>
<Text style={{ alignSelf: 'center' }}>
No products match the selected criteria
</Text>
</View>
)}
</Content>
);
};
const styles = StyleSheet.create({
center: {
justifyContent: 'center',
alignItems: 'center',
height: 100
}
})
export default SearchedProduct;
Please can anyone help me to solve this error .If you want I will provide other details of my code.
Thanks in advance
Not sure but you are using SearchProduct name as a component and at the same time as a method. Maybe try to rename changing either component name or method name to see if it works.

Why can not I enter texts continually when using TexInput component with a props

I am trying to make a TextInput component as a child with a function which is from the parent component.
but then, I can't enter texts as usual(I have to set the cursor every after I enter 1 text )
would you mind tell me how to resolve this problem?
thank you in advance.
the parent component
import React, { useState, useEffect } from "react";
import { View, StyleSheet } from "react-native";
import TestListInputItem from "../components/TestListInputItem";
export default function HomeScreen() {
const [name, setName] = useState("");
const setInputName = (text) => {
setName(text);
};
return (
<View style={styles.container}>
<TestListInputItem name={name} setInputName={setInputName} />
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
},
});
the child component
import React, { useState } from "react";
import {
View,
StyleSheet,
Text,
TouchableOpacity,
TextInput,
} from "react-native";
export default function TestListInputItem(props) {
const [count, setCount] = useState(1);
function handleMakeNew() {
setCount((v) => v + 1);
}
function RenderList() {
return (
<View style={styles.list}>
<TextInput
style={styles.InputName}
value={String(props.name)}
onChangeText={(text) => {
props.setInputName(text);
}}
></TextInput>
<TouchableOpacity
onPress={() => {
handleMakeNew();
}}
style={styles.buttonAdd}
>
<Text>Add</Text>
</TouchableOpacity>
</View>
);
}
return [...Array(count).keys()].map((i) => <RenderList key={i} />);
}
const styles = StyleSheet.create({
list: {
width: "100%",
backgroundColor: "#ddd",
padding: 10,
},
InputName: {
borderWidth: 1,
height: 40,
backgroundColor: "#fff",
},
buttonAdd: {
backgroundColor: "orange",
width: 80,
height: 40,
margin: 3,
justifyContent: "center",
alignItems: "center",
alignSelf: "center",
},
});
Node: 12.18.3
React-Native: 4.10.1
Expo: 3.22.3
As I commented, the issues is that your function is creating a new array on every render resetting your state, here's a quick modification that should set you in the right direction
export default function AddItem(props) {
return (
<View style={styles.list}>
<TextInput
style={styles.InputName}
value={props.value}
onChangeText={(text) => {
props.setValue(text);
}}
></TextInput>
</View>
);
}
export default function TestListInputItem(props) {
const [list, setList] = useState([]);
const [value, setValue] = useState("");
function handleMakeNew() {
setList((v) => [...v, value]);
}
return (
<View>
{
list.map((item, i) => <View key={i}><Text>{item}</Text></View>)
}
<AddItem
value={value}
setValue={setValue}
/>
<TouchableOpacity
onPress={() => {
handleMakeNew();
}}
style={styles.buttonAdd}
>
<Text>Add</Text>
</TouchableOpacity>
</View>
)
}
This is known as cursor jumping. To avoid this, in your Input component, maintain a local state and use that state value as input value. when onChange is fired, update the local state value first and then send it to the parent component
Try this in the child component,
import React, { useState } from "react";
import {
View,
StyleSheet,
Text,
TouchableOpacity,
TextInput,
} from "react-native";
export default function TestListInputItem(props) {
const [count, setCount] = useState(1);
const [inputValue, setInputValue] = useState('');
function handleMakeNew() {
setCount((v) => v + 1);
}
const handleInput =(text) =>{
setInputValue(text)
props.setInputName(text)
}
function RenderList() {
return (
<View style={styles.list}>
<TextInput
style={styles.InputName}
value={inputValue}
onChangeText={(text) => {
handleInput(text);
}}
></TextInput>
<TouchableOpacity
onPress={() => {
handleMakeNew();
}}
style={styles.buttonAdd}
>
<Text>Add</Text>
</TouchableOpacity>
</View>
);
}

Unexpected token, expected ";" in react native

I am a newbie in react native, I am developing a video app to aid my learning curve. In the code below I have tried all I could to solve the error on the "displayModal" line, but could not. Please can anyone help me with this.
I want on image/video capture it will display on the modal and from the modal i will be able to "Discard", or "Save"(to firebase), or "Share" the image/video.
import React from 'react';
import { View, Text, Image, Modal, TouchableOpacity } from 'react-native';
import { Ionicons } from '#expo/vector-icons';
import styles from './styles';
export default ({captures=[]}) => {
state = {
isVisible: false
}
// hide show modal
displayModal(show){ ------this is where am getting the error
this.setState({isVisible: show})
}
return (
<Modal
transparent={true}
visible={this.state.isVisible}
// style={[styles.bottomToolbar, styles.galleryContainer]}
>
<View style={{backgroundColor: "#000000aa", flex: 1}}>
{captures.map(({ uri }) => (
<View style={styles.galleryImageContainer} key={uri}>
<Image source={{ uri }} style={styles.galleryImage} />
</View>
))}
</View>
<TouchableOpacity style={{justifyContent: 'center', alignItems: 'center'}}>
<Ionicons
name="close-outline"
color="white"
size={20}
onPress={() => {this.displayModal(!this.state.isVisible);}}
/>
<Text>Discard</Text>
</TouchableOpacity>
</Modal>
);
};
click here to see error image
From you code it looks like a functional component, but you are using state as class-based component, that might be the reason you are getting error :
export default ({captures=[]}) => {
state = {
isVisible: false
}
// hide show modal
displayModal(show){ ------this is where am getting the error
this.setState({isVisible: show})
}
Above code block should look like this :
export default ({captures=[]}) => {
const [state,setState] = useState({ isVisible: false })
// hide show modal
const displayModal = (show) => {
setState({isVisible: show})
}
You are mixing functional component with class component.
"this.state" and "this.setState" belong to class components and all the rest belongs to functional components.
Try to change this:
state = {
isVisible: false
}
// hide show modal
displayModal(show){ ------this is where am getting the error
this.setState({isVisible: show})
}
To this:
const [isVisible, setIsVisible] = React.useState(false);
const displayModal = show => setIsVisible(show);
In addition, in the return statement, remove the strings/words "this" and "this.state".
Requested addition:
import React, { useState } from 'react';
import { View, Text, Image, Button, Modal, TouchableOpacity } from 'react-native';
import { Ionicons } from '#expo/vector-icons';
import { storage } from './fbstorage';
import { Camera } from 'expo-camera';
import styles from './styles';
export default ({ captures = [] }) => {
const [isVisible, setIsVisible] = useState(false);
const takePicture = async () => {
const photoData = await Camera.takePictureAsync();
if (!photoData.cancelled) {
uploadImage(photoData.uri, imageName)
.then(() => {
Alert.alert("Success");
})
.catch((error) => {
Alert.alert('Error:', error.message);
});
}
}
const uploadImage = async (uri, imageName) => {
const response = await fetch(uri);
const blob = await response.blob();
var ref = storage().ref().child("images/" + imageName);
return ref.put(blob)
}
return (
<Modal
transparent={true}
visible={isVisible}
// style={[styles.bottomToolbar, styles.galleryContainer]}
>
<View style={{ backgroundColor: "#000000aa", flex: 1 }}>
{captures.map(({ uri }) => (
<View style={styles.galleryImageContainer} key={uri}>
<Image source={{ uri }} style={styles.galleryImage} />
</View>
))}
</View>
<TouchableOpacity
style={{
justifyContent: 'center',
alignItems: 'center',
marginTop: 20,
top: -20
}}
onPress={() => setIsVisible(false)}
>
<Ionicons
name="md-reverse-camera"
color="white"
size={40}
/>
<Text style={{ color: 'white' }}>Discard</Text>
</TouchableOpacity>
<Button
title='Save'
onPress={takePicture}
/>
</Modal>
);
};

I keep getting this error. TypeError: addItems is not a function. (In 'addItems(text)', 'addItems' is an instance of Object)

This is the error I get every time I try and add something to my list.
TypeError: addItems is not a function. (In 'addItems(text)', 'addItems' is an instance of Object)
I cannot figure out what I am doing wrong. Im new to react-native so any help would be greatly appreciated.
Here is my App.js
import React, { useState } from 'react';
import { View, Text, StyleSheet, ImageBackground, FlatList } from 'react-native';
import 'react-native-get-random-values';
import { v4 as uuidv4 } from 'uuid';
import { uuid } from 'uuidv4';
import Header from './Componets/Header';
import AddItem from './Componets/AddItem';
import background from './Images/sunrise-in-the-smoky-mountains.jpg';
import ListItem from './Componets/ListItem';
const App = () => {
const [item, setItems] = useState([
// {
// id: uuidv4(),
// name: ''
// },
{
id: uuidv4(),
name: "gym"
},
{
id: uuidv4(),
name: "study"
}
]);
const addItems = (text) => {
setItems(prevItems => {
return [{ id: uuidv4(), text }, ...prevItems]
})
}
const deleteItem = (id) => {
setItems(prevVal => {
return prevVal.filter(item => item.id != id)
})
}
return (
<View style={styles.container}>
<ImageBackground source={background} style={styles.image}>
<Header
title="Gotta get this done!" />
<AddItem
addItem={addItems}
/>
<FlatList
data={item}
renderItem={({ item }) => (
<ListItem item={item.name} deleteItem={deleteItem} />
)}
/>
</ImageBackground>
</View>
)
};
const styles = StyleSheet.create({
container: {
flex: 1,
},
image: {
flex: 1,
resizeMode: "cover",
justifyContent: "center"
}
})
export default App;
Here is where I call the function and get the error.
import React, { useState } from 'react';
import { View, Text, StyleSheet, TextInput, TouchableOpacity, Button } from 'react-native';
const AddItem = ( addItems ) => {
const [text, setText] = useState("");
const onChange = (inputVal) => setText(inputVal);
return (
<View style={styles.addItemView}>
<TextInput
style={styles.inputText}
placeholder="Add item to list..."
onChangeText={onChange}
/>
<TouchableOpacity style={styles.button}>
<Button title="Add Item" onPress={() => addItems(text)} />
</TouchableOpacity>
</View>
);
};
const styles = StyleSheet.create({
addItemView: {
flex: 1,
flexDirection: "row",
alignItems: 'center'
},
inputText: {
fontSize: 20,
backgroundColor: "white",
alignItems: 'center',
justifyContent: 'center',
borderWidth: 1,
width: 250,
},
button: {
alignItems: "center",
justifyContent: "center",
height: 40,
backgroundColor: "#bbc7ad",
borderRadius: 10,
borderWidth: 2,
borderColor: "#99a191",
marginLeft: 20,
}
})
export default AddItem;
You are passing addItems function as a prop in
<AddItem
addItem={addItems}
/>
When you pass any function or value to any functional component in React you can access them only via props so to access addItems you need to access this function from the props
You can do that by following ways
Method 1
const AddItem = ( props ) => {
// We are extracting addItem function from props
const {addItem} = props
const [text, setText] = useState("");
const onChange = (inputVal) => setText(inputVal);
return (
<View style={styles.addItemView}>
<TextInput
style={styles.inputText}
placeholder="Add item to list..."
onChangeText={onChange}
/>
<TouchableOpacity style={styles.button}>
<Button title="Add Item" onPress={() => addItem(text)} />
</TouchableOpacity>
</View>
);
};
Method 2 :
const AddItem = ({addItem} ) => {
.....
return (
<View style={styles.addItemView}>
......
<TouchableOpacity style={styles.button}>
<Button title="Add Item" onPress={() => addItem(text)} />
</TouchableOpacity>
</View>
);
};
This seems to work for now. Still unclear as to why using destructuring in my original version didnt work. Please chime in if you can help with that. Thanks!
const AddItem = (props) => {
const [text, setText] = useState("");
const onChange = inputVal => setText(inputVal);
return (
<View style={styles.addItemView}>
<TextInput
style={styles.inputText}
placeholder="Add item to list..."
onChangeText={onChange}
/>
<TouchableOpacity style={styles.button}>
<Button title="Add Item" onPress={() => props.addItem(text)} />
</TouchableOpacity>
</View>
);
};

Login not going to HomeScreen

My login not going to HomeScreen, but when I reload the app it will automatically go to HomeScreen? The login functionality works fine the only thing that bugging me right now, it needs to reload the app before it will go to HomeScreen.
Below are the file for my App, LoadingScreen, LoginScreen, and HomeScreen.
App.js
import React, { useEffect, useState } from 'react';
import { NavigationContainer } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
import SignupScreen from './screens/SignupScreen';
import LoginScreen from './screens/LoginScreen';
import LoadingScreen from './screens/LoadingScreen';
import HomeSceen from './screens/HomeScreen';
import AsyncStorage from '#react-native-community/async-storage';
const App = ({ navigation }) => {
const [isloggedin, setLogged] = useState(null);
const detectLogin = async () => {
const token = await AsyncStorage.getItem('token');
if (token !== null) {
setLogged(true);
} else {
setLogged(false);
}
};
useEffect(() => {
detectLogin();
}, []);
const StackApp = createStackNavigator();
return (
<NavigationContainer>
<StackApp.Navigator headerMode="none">
<StackApp.Screen name="loading" component={LoadingScreen} />
<StackApp.Screen name="home" component={HomeSceen} />
<StackApp.Screen name="login" component={LoginScreen} />
<StackApp.Screen name="signup" component={SignupScreen} />
</StackApp.Navigator>
</NavigationContainer>
);
}
export default App;
LoadingScreen.js
import React, { useEffect } from 'react';
import {
ActivityIndicator,
View,
StyleSheet
} from 'react-native';
import AsyncStorage from '#react-native-community/async-storage';
const LoadingScreen = (props) => {
const detectLogin = async () => {
const token = await AsyncStorage.getItem('token');
if (token) {
props.navigation.replace("home");
} else {
props.navigation.replace("login");
}
};
useEffect(() => {
detectLogin();
}, []);
return (
<View style={styles.loading}>
<ActivityIndicator size="large" color="#ff0550" />
</View>
);
};
const styles = StyleSheet.create({
loading: {
flex: 1,
justifyContent: "center",
alignItems: "center"
},
});
export default LoadingScreen;
LoginScreen.js
import React, { useState } from 'react';
import { Button, TextInput } from 'react-native-paper';
import {
View,
Text,
StatusBar,
TouchableOpacity,
KeyboardAvoidingView,
Alert,
} from 'react-native';
import AsyncStorage from '#react-native-community/async-storage';
import { SafeAreaView } from 'react-native-safe-area-context';
const LoginScreen = (props) => {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const handleLogin = async (props) => {
fetch('http://localhost:3000/api/auth/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
'email': email,
'password': password,
}),
})
.then(res => res.json())
.then(async (data) => {
try {
const items = [['token', data.token], ['user', data.user._id]];
AsyncStorage.multiSet(items);
props.navigation.replace('home');
} catch (e) {
console.log('error log', data.error);
Alert(data.error);
}
});
};
return (
<SafeAreaView style={{ flex: 1 }}>
<KeyboardAvoidingView behavior="position">
<StatusBar backgroundColor="#ff0550" barStyle="light-content" />
<View
style={{
borderBottomColor: '#ff0550',
borderBottomWidth: 4,
borderRadius: 10,
marginLeft: 20,
marginRight: 150,
marginTop: 4,
}}
/>
<Text
style={{
fontSize: 20, marginLeft: 18, marginTop: 20
}}
>Login with email</Text>
<TextInput
label='Email'
autoCapitalize="none"
mode="outlined"
value={email}
style={{ marginLeft: 18, marginRight: 18, marginTop: 18 }}
theme={{ colors: { primary: '#ff0550' } }}
onChangeText={(text) => setEmail(text)}
/>
<TextInput
label='password'
autoCapitalize="none"
mode="outlined"
secureTextEntry={true}
value={password}
onChangeText={(text) => { setPassword(text) }}
style={{ marginLeft: 18, marginRight: 18, marginTop: 18 }}
theme={{ colors: { primary: '#ff0550' } }}
/>
<Button
mode="contained"
style={{ marginLeft: 18, marginRight: 18, marginTop: 18, backgroundColor: '#ff0550' }}
onPress={() => handleLogin(props)}>
Login
</Button>
<TouchableOpacity>
<Text
style={{
fontSize: 18, marginLeft: 18, marginTop: 20
}}
onPress={() => props.navigation.replace('signup')}
>dont have a account ?</Text>
</TouchableOpacity>
</KeyboardAvoidingView>
</SafeAreaView>
);
};
export default LoginScreen;
HomeScreen.js
import React, { useEffect, useState } from 'react';
import { Button } from 'react-native-paper';
import { Text, View } from 'react-native';
import AsyncStorage from '#react-native-community/async-storage';
const HomeScreen = (props) => {
const logout = (props) => {
let keys = ['user', 'token'];
AsyncStorage.multiRemove(keys, (error) => {
props.navigation.replace('login');
});
};
return (
<View style={{ flex: 1, marginTop: 100 }}>
<Text style={{ fontSize: 18 }}>your email is sample here!</Text>
<Button
mode="contained"
style={{ marginLeft: 18, marginRight: 18, marginTop: 18, backgroundColor: '#ff0550' }}
onPress={() => logout(props)}
>
logout
</Button>
</View>
);
};
export default HomeScreen;
user props.navigation.navigate("Homescreen")
Also,you need add condition in app js if logged then go to homescreen else login page.
Check switch Navigator too from react-navigation
Replace just change current screen to another screen instead of navigating through screen. so it will stay that screen only

Resources