React native app crashes on logout for first launch - javascript

I have been created a react native app,on first launch of the app it go to the route appjs->onboardingscreen->loginscreen->tabscreen and in tab screen there are 3 tabs on the last tab profile there is the function that clear context and storage to log out but on preforming that it crashes.that error shows that it previous stack context value is null but on second launch the app work perfect on the route loginscreen->tabscrenn afterwords its log out perfect
import React, { useContext } from "react";
import { View, StyleSheet, Text, SafeAreaView, ScrollView, TouchableOpacity } from "react-native";
import HeaderLayout from "../../Components/HeaderLayout";
import Statusbar from "../../Components/Statusbar";
import MaterialCommunityIcons from "react-native-vector-icons/MaterialCommunityIcons";
import Profile_Detail_Tab from "../../Components/Profile_Detail_Tab";
import AuthContext from "../../auth/context";
import storage from "../../auth/storage";
import { useBottomTabBarHeight } from "#react-navigation/bottom-tabs";
function Profile({ navigation }) {
const tabheight = useBottomTabBarHeight();
const { userData, setUserData } = useContext(AuthContext);
const key = "#storage_Key";
console.log("profile");
const handleLogOut = () => {
setUserData(null);
storage.removeData(key);
console.log("logout");
};
return (
<SafeAreaView>
<Statusbar />
<HeaderLayout title={"Profile"} />
<ScrollView>
<View style={{ backgroundColor: "#ffffff", paddingBottom: tabheight, marginBottom: 10 }}>
<View
style={{
width: "100%",
height: 100,
backgroundColor: "#04213c",
borderBottomEndRadius: 50,
borderBottomStartRadius: 50,
}}
/>
<View style={styles.container}>
<MaterialCommunityIcons name="account" size={140} color="white" />
</View>
<Text style={{ marginLeft: 30, padding: 10, fontSize: 20, fontWeight: "bold" }}>
{userData.detail.first_name + " " + userData.detail.last_name}
</Text>
<View>
<Profile_Detail_Tab text_color="#000000" color="#ffffff" Title="email" value={userData.detail.email} />
<Profile_Detail_Tab text_color="#000000" color="#ffffff" Title="phone" value={userData.detail.mobile} />
<Profile_Detail_Tab
text_color="#000000"
color="#ffffff"
Title="map-marker-outline"
value={userData.detail.work_station}
/>
<Profile_Detail_Tab
text_color="#000000"
color="#ffffff"
Title="account-hard-hat"
value={userData.detail.role}
/>
<Profile_Detail_Tab
text_color="#000000"
color="#ffffff"
Title="message-reply-text"
value={userData.detail.designation}
/>
<TouchableOpacity onPress={handleLogOut}>
<Profile_Detail_Tab text_color="#ffffff" color="#04213c" Title="logout" value="Logout" />
</TouchableOpacity>
</View>
</View>
</ScrollView>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
container: {
backgroundColor: "#d1c9d3",
borderRadius: 15,
width: 140,
height: 140,
borderRadius: 70,
marginLeft: 30,
marginTop: -80,
},
});
export default Profile;
[
import { NavigationContainer } from "#react-navigation/native";
import React, { useEffect, useState } from "react";
import Tabs from "./src/Navigation/Tabs";
import StackNavigation from "./src/Navigation/StackNavigation";
import AuthContext from "./src/auth/context";
import storage from "./src/auth/storage";
import AppLoading from "expo-app-loading";
import AsyncStorage from "#react-native-community/async-storage";
import AuthNavigation from "./src/Navigation/AuthNavigation";
import { ActivityIndicator, Text, View } from "react-native";
function App() {
const [userData, setUserData] = useState();
const key = "#storage_Key";
const [isReady, setIsReady] = useState(false);
const [isFirstLaunch, setIsFirstLaunch] = useState(null);
useEffect(() => {
checkdata();
}, []);
console.log("App js");
const checkdata = async () => {
const appData = await AsyncStorage.getItem("isAppFirstLaunched");
if (appData == null) {
setIsFirstLaunch(true);
AsyncStorage.setItem("isAppFirstLaunched", "false");
} else {
setIsFirstLaunch(false);
}
};
// console.log(isFirstLaunch);
const getToken = async () => {
const data = await storage.getData(key);
if (data == null) return;
setUserData(data);
console.log(data);
};
console.log(userData);
if (!isReady) return <AppLoading startAsync={getToken} onFinish={() => setIsReady(true)} onError={console.warn} />;
if (isFirstLaunch == null) {
return (
<View style={{ flex: 1 }}>
<ActivityIndicator size="large" />
</View>
);
} else if (isFirstLaunch == true) {
return (
<AuthContext.Provider value={{ userData, setUserData }}>
<NavigationContainer>
<StackNavigation />
</NavigationContainer>
</AuthContext.Provider>
);
} else {
return (
<AuthContext.Provider value={{ userData, setUserData }}>
<NavigationContainer>{userData ? <Tabs /> : <AuthNavigation />}</NavigationContainer>
</AuthContext.Provider>
);
}
}
export default App;
]1
enter image description here
import { NavigationContainer } from "#react-navigation/native";
import React, { useEffect, useState } from "react";
import Tabs from "./src/Navigation/Tabs";
import StackNavigation from "./src/Navigation/StackNavigation";
import AuthContext from "./src/auth/context";
import storage from "./src/auth/storage";
import AppLoading from "expo-app-loading";
import AsyncStorage from "#react-native-community/async-storage";
import AuthNavigation from "./src/Navigation/AuthNavigation";
import { ActivityIndicator, Text, View } from "react-native";
function App() {
const [userData, setUserData] = useState();
const key = "#storage_Key";
const [isReady, setIsReady] = useState(false);
const [isFirstLaunch, setIsFirstLaunch] = useState(null);
useEffect(() => {
checkdata();
}, []);
console.log("App js");
const checkdata = async () => {
const appData = await AsyncStorage.getItem("isAppFirstLaunched");
if (appData == null) {
setIsFirstLaunch(true);
AsyncStorage.setItem("isAppFirstLaunched", "false");
} else {
setIsFirstLaunch(false);
}
};
// console.log(isFirstLaunch);
const getToken = async () => {
const data = await storage.getData(key);
if (data == null) return;
setUserData(data);
console.log(data);
};
console.log(userData);
if (!isReady) return <AppLoading startAsync={getToken} onFinish={() => setIsReady(true)} onError={console.warn} />;
if (isFirstLaunch == null) {
return (
<View style={{ flex: 1 }}>
<ActivityIndicator size="large" />
</View>
);
} else if (isFirstLaunch == true) {
return (
<AuthContext.Provider value={{ userData, setUserData }}>
<NavigationContainer>
<StackNavigation />
</NavigationContainer>
</AuthContext.Provider>
);
} else {
return (
<AuthContext.Provider value={{ userData, setUserData }}>
<NavigationContainer>{userData ? <Tabs /> : <AuthNavigation />}</NavigationContainer>
</AuthContext.Provider>
);
}
}
export default App;

use userData?.detail instead of userData.detail coz its getting undefined where you shown error in image

Related

I have a problem with my provider to render different navigator stacks

I am implementing a provider which helps me to have the state of my user in different views, the main function of this provider is to render different one or the other stack navigator depending on whether the variable is full or empty, this in order to be able to generate two groups of screens depending on whether the user is authenticated or not.
Here my code:
View router.tsx:
import { NavigationContainer } from "#react-navigation/native"
import React, { useContext, useEffect, useState, useRef } from "react"
import { UserContext } from "./context/Usuario"
import AuthStack from "./routes/AuthStack"
import GeneralStack from "./routes/GeneralStack"
const Router = () => {
const { me } = useContext(UserContext)
const auth = useRef(false)
useEffect(() => {
return () => {
auth.current = me !== null
console.log("Hola")
}
}, [me])
return (
<NavigationContainer>
{auth.current ? <GeneralStack /> : <AuthStack />}
</NavigationContainer>
)
}
export default Router
Provider user,js:
import React, { useEffect, createContext, useState } from "react"
import AsyncStorage from "#react-native-async-storage/async-storage"
export const UserContext = createContext()
const UserProvider = ({ children }) => {
const [me, setMe] = useState(undefined)
const validStorage = async () => {
try {
const miSesion = await AsyncStorage.getItem("sesion")
console.log(miSesion)
setMe(JSON.parse(miSesion))
} catch (error) {
console.log(`ERROR: ${error.message}`)
}
}
useEffect(() => {
validStorage()
}, [])
return (
<UserContext.Provider value={{ me, setMe }}>
{children}
</UserContext.Provider>
)
}
export default UserProvider
GeneralStack:
import { createNativeStackNavigator } from "#react-navigation/native-stack"
import React from "react"
import TabStack from "./TabStack"
//import TabStack from "./TabStack"
const GeneralScreen = createNativeStackNavigator()
const GeneralStack = () => {
return (
<GeneralScreen.Navigator screenOptions={{ headerShown: false }}>
<GeneralScreen.Screen name="Tabs" component={TabStack} />
</GeneralScreen.Navigator>
)
}
export default GeneralStack
AuthStack:
import { createNativeStackNavigator } from "#react-navigation/native-stack"
import React from "react"
import Login from "../Screens/Login"
import Registro from "../Screens/Registro/Registro"
import SplashScreen from "../SplashScreen"
const AuthScreen = createNativeStackNavigator()
const AuthStack = () => {
return (
<AuthScreen.Navigator
initialRouteName="Splash"
screenOptions={{ headerShown: false }}>
<AuthScreen.Screen name="Login" component={Login} />
<AuthScreen.Screen name="Register" component={Registro} />
<AuthScreen.Screen name="Splash" component={SplashScreen} />
</AuthScreen.Navigator>
)
}
export default AuthStack
Login:
import React, { useState, useContext } from "react"
import {
Image,
ScrollView,
StatusBar,
Text,
TouchableOpacity,
View,
} from "react-native"
import { useNavigate } from "../../Hooks/useNavigate"
import MyTextInput from "../../components/MyTextInput"
import colors from "../../styles/colors"
import { loginStyles } from "../../styles/styles"
import { UserContext } from "../../context/Usuario"
import AsyncStorage from "#react-native-async-storage/async-storage"
export default function Login() {
const [, setIsSession] = useState(false)
const { setMe } = useContext(UserContext)
const navigate = useNavigate()
const [hidePassword, sethidePassword] = React.useState(false)
const [user] = useState({ user: "admin", password: "admin123" })
const [form, setForm] = useState({ user: "", password: "" })
const getStorage = async () => {
if (await AsyncStorage.getItem("sesion")) {
setIsSession(true)
} else {
setIsSession(false)
}
}
const signIn = async () => {
try {
console.log(user)
if (form.user === user.user && form.password === user.password) {
await AsyncStorage.setItem("sesion", JSON.stringify(form))
setMe(form)
setIsSession(true)
}
} catch (error) {
console.error(error)
}
}
const closeSesion = async () => {
await AsyncStorage.removeItem("sesion")
getStorage()
}
return (
<ScrollView contentContainerStyle={[loginStyles.container]}>
<StatusBar backgroundColor={colors.PURPLE} translucent={true} />
<View style={loginStyles.logo}>
<Image
source={require("../../recursos/images/Logo.png")}
style={{ height: 250, width: 250 }}
/>
</View>
<MyTextInput
onChangeText={(text: string) => {
setForm(state => ({ ...state, user: text }))
}}
keyboardType="email-address"
placeholder="E-mail"
/>
<MyTextInput
onChangeText={(text: string) => {
setForm(state => ({ ...state, password: text }))
}}
keyboardType={null}
placeholder="Contraseña"
bolGone={true}
secureTextEntry={hidePassword}
onPress={() => sethidePassword(!hidePassword)}
/>
<View style={loginStyles.btnMain}>
<TouchableOpacity onPress={signIn}>
<Text style={loginStyles.btntxt}>Iniciar Sesión</Text>
</TouchableOpacity>
</View>
<View style={loginStyles.btnTransparent}>
<TouchableOpacity
onPress={() => navigate({ screen: "Register" })}>
<Text
style={[loginStyles.btntxt, { color: colors.PURPLE }]}>
Registrarse
</Text>
</TouchableOpacity>
</View>
<View>
<TouchableOpacity>
<Text
style={[
loginStyles.txtTransparent,
{ textDecorationLine: "none" },
]}>
Olvide mi contraseña
</Text>
</TouchableOpacity>
</View>
</ScrollView>
)
}
Home:
import AsyncStorage from "#react-native-async-storage/async-storage"
import React, { useState } from "react"
import { Image, ScrollView, TouchableOpacity } from "react-native"
import { Calendar } from "react-native-calendars"
import { Text } from "react-native-elements"
import { useNavigate } from "../../Hooks/useNavigate"
import colors from "../../styles/colors"
const Home = () => {
const [showModal, setShowModal] = useState(false)
const [date, setDate] = useState<string>()
const navigate = useNavigate()
const [isSession, setIsSession] = useState(false)
const getStorage = async () => {
const data = await AsyncStorage.getItem("sesion")
console.log(data)
if (data) {
setIsSession(true)
} else {
setIsSession(false)
}
}
const closeSesion = async () => {
await AsyncStorage.removeItem("sesion")
getStorage()
}
return (
<ScrollView>
<TouchableOpacity onPress={() => closeSesion()}>
<Text>Hola porque soy bien molon</Text>
</TouchableOpacity>
<Image
source={require("../../recursos/images/coralio_logo.png")}
style={{
marginTop: 40,
height: 110,
width: "80%",
justifyContent: "center",
alignSelf: "center",
}}
/>
<Calendar
theme={{
selectedDayBackgroundColor: colors.BLACK,
arrowColor: colors.WHITE,
monthTextColor: colors.WHITE,
}}
style={{
backgroundColor: colors.PURPLE,
borderRadius: 10,
elevation: 4,
marginTop: 60,
margin: 10,
height: 400,
}}
onDayPress={day => {
console.log(day.dateString)
setDate(day.dateString)
setShowModal(false)
}}
onMonthChange={() => {}}
initialDate={"2023-01-16"}
minDate={new Date()
.toLocaleDateString("es-US", {
year: "numeric",
month: "2-digit",
day: "numeric",
formatMatcher: "basic",
})
.split("/")
.reverse()
.join("-")}
markedDates={{
day: {
marked: true,
dotColor: colors.WHITE,
selected: true,
selectedColor: colors.PURPLE,
},
}}
//maxDate={"2023-12-31"}
//hideExtraDays={false}
//disableArrowLeft={true}
//disableArrowRight={true}
//hideArrows={true}
//hideDayNames={true}
/>
</ScrollView>
)
}
export default Home
The problem I have is when doing the close session in home, if in login it sends me from the authstack view to generalstack, when I do the close session it doesn't send me back to login, but it does clean the state of the variable from asyncstorage.
Help :(
It looks like you're not clearing the me variable in your context when the user ends the session. I think your closeSesion method should look like this:
const closeSesion = async () => {
setMe(null)
await AsyncStorage.removeItem("sesion")
getStorage()
}

Ways to stop re-rendering when a state is changed ? (React Native)

Let me summarize a lil bit, what I'm trying to do is when the news is clicked, a modal (in this case I used a library: react-native-modalize https://github.com/jeremybarbet/react-native-modalize) is presented with the respective details of the clicked news
In order for the content inside the modal to be dynamic, I used states to store the details, so whenever a click is registered on the news, a series of details is passed thru function parameters and store in the respective state
THE PROBLEM is that whenever a state on the top level is changed the whole component refresh itself, and it's causing problem like:
Scenario 1: when the user scroll until the end of the scroll view and pressed on one of the news, modal is brought up and because the state is being changed, the whole app refreshes and the scroll view jumps back to the top.
app.js
import { StatusBar } from 'expo-status-bar';
import React from 'react';
import { useRef, useState, useEffect } from 'react';
import { AppLoading } from 'expo'
import { StyleSheet, Text, View, FlatList, SafeAreaView, ScrollView, Image, TouchableOpacity } from 'react-native';
import { NavigationContainer } from '#react-navigation/native';
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs';
import { Modalize } from 'react-native-modalize';
import { Ionicons } from '#expo/vector-icons';
import { render } from 'react-dom';
import Header from './components/Header';
import NuaDaily from './components/Daily';
import Content from './components/Content';
import moment from "moment";
const HomeStackScreen = () => {
const [title, setTitle] = useState([])
const [author, setAuthor] = useState([])
const [publication, setPublication] = useState([])
const [imageUrl, setImageUrl] = useState([])
const [summary, setSummary] = useState([])
const modalizeRef = useRef(null);
const onOpen = (title, author, publication, imageUrl, summary) => {
modalizeRef.current?.open();
setTitle(title)
setAuthor(author)
setPublication(publication)
setImageUrl(imageUrl)
setSummary(summary)
};
return (
<>
<SafeAreaView style={styles.container}>
<ScrollView style={styles.scrollView}>
<View style={styles.container}>
<Header />
<NuaDaily modalize={onOpen} style={styles.nuadaily} />
<Content modalize={onOpen} />
</View>
</ScrollView>
</SafeAreaView>
<Modalize snapPoint={650} modalTopOffset={10} ref={modalizeRef} style={{ width: '100%', alignItems: 'center', justifyContent: 'center', padding: 20 }}>
<View style={{padding: 20}}>
<Image
style={{width: 350, height: 200, zIndex: 1000, borderRadius: 8, marginTop: 10}}
source={{ uri: `${imageUrl}` }}
/>
<Text style={styles.modalTitle}>{title}</Text>
<View style={styles.detailsBar}>
<Text style={styles.modalAuthor}>{author}</Text>
<Text style={styles.modalPublication}>{moment(publication).format("MM-DD-YYYY")}</Text>
</View>
<Text style={styles.modalSummary}>{summary}</Text>
</View>
</Modalize>
</>
)
}
const Tab = createBottomTabNavigator();
export default function App() {
return (
<NavigationContainer>
<Tab.Navigator
tabBarOptions={
{
activeTintColor: '#00B2FF',
inactiveTintColor: 'gray',
showLabel: false,
style: { height: 60, borderRadius: 0, backgroundColor: 'rgba(255, 255, 255, 0.85)'}
}
}
showLabel = {false}
screenOptions={({ route }) => ({
tabBarIcon: ({ focused, color, size }) => {
if (route.name === 'Home') {
return <HomeIcon />
}
},
})}
>
<Tab.Screen name="Home"
component={
HomeStackScreen
} />
</Tab.Navigator>
</NavigationContainer>
);
}
});
Daily (index.js) (imported on app.js)
import React from 'react';
import { useState, useEffect } from 'react';
import {View, Text, FlatList, Image, ImageBackground, ScrollView, SafeAreaView, TouchableOpacity} from 'react-native';
import axios from 'axios';
import moment from "moment";
import * as Font from 'expo-font';
import AppLoading from 'expo-app-loading';
import { useFonts } from 'expo-font';
import styles from './style';
import Dot from '../../assets/images/dot.svg';
const nuaDaily = ( props ) => {
const Item = ({ title, author, publication, imageUrl, summary }) => (
<View style={styles.item}>
<TouchableOpacity onPress={()=>props.modalize(title, author, publication, imageUrl, summary)}>
<Image
style={{width: 210, height: 200, zIndex: 1000, borderRadius: 8, marginTop: 10}}
source={{ uri: `${imageUrl}` }}
/>
<Text style={ [styles.title, {fontFamily: 'Poppins'}]}>{title}</Text>
<View style={styles.bottomBar}>
<Text style={styles.author}>{author}</Text>
<Text style={styles.publication}>{moment(publication).format("MM-DD-YYYY hh:mm")}</Text>
</View>
</TouchableOpacity>
</View>
);
const renderItem = ({ item }) => {
if(moment(item.publication).isSame(moment(), 'day')){
return <Item title={item.title} author={item.newsSite} publication={item.publishedAt} imageUrl={item.imageUrl} summary={item.summary} />
}else{
// return <Item title={item.title} author={item.newsSite} publication={item.publishedAt} imageUrl={item.imageUrl} summary={item.summary} />
}
};
const [data, setData] = useState([])
useEffect(() => {
axios.get(APIURL)
.then((res) => {
setData(res.data)
})
.catch((err) => {
console.log(`error calling API ${err}`)
})
},[])
return (
<View style={styles.container}>
<View style={styles.containerTitle}>
<Dot style={styles.dot} />
<Text style={ [styles.PrimaryText , {fontFamily: 'Quicksand'}]}>NUA Daily</Text>
</View>
<FlatList
showsHorizontalScrollIndicator={false}
horizontal={true}
data={data}
renderItem={renderItem}
style={styles.flatList}
/>
</View>
)
}
export default nuaDaily;
Demo of the problem (Scenario 1)

Not sure how to include function in useEffect

I am trying to mount a function within useEffect, how would I call this function within useEffect, I am not sure?
Initially useEffect is written as following in the app-
useEffect(() => {
CognitensorEndpoints.getDashboardList({
dispatchReducer: dispatchDashboards,
});
CognitensorEndpoints.getList({
dispatchReducer: dispatchDashboards,
});
},[]);
Then when I include useEffect as below, it returns errors ('Cannot read property 'filter' of undefined') -
useEffect(() => {
console.log('abcd');
setLoading();
CognitensorEndpoints.getDashboardList({
dispatchReducer: dispatchDashboards,
});
CognitensorEndpoints.getList({
dispatchReducer: dispatchDashboards,
});
},[]);
How do I correctly include 'setLoading()' within useEffect?
Here's the full app code-
import React, { useState, useEffect, useReducer } from 'react';
import { View, Text, StyleSheet, FlatList, ActivityIndicator, Keyboard, Button } from 'react-native';
import { Searchbar } from 'react-native-paper';
import { theme } from '../theme';
import MaterialIcons from 'react-native-vector-icons/MaterialIcons';
import { TouchableOpacity } from 'react-native-gesture-handler';
import { apiStateReducer } from '../reducers/ApiStateReducer';
import CognitensorEndpoints from '../services/network/CognitensorEndpoints';
import DefaultView from '../components/default/DefaultView';
import DashboardListCard from '../components/DashboardListCard';
import DashboardHeader from '../components/DashboardHeader';
import DashboardGridCard from '../components/DashboardGridCard';
import {
NavigationContainer,
useFocusEffect,
} from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs';
const AppHeader = ({
scene,
previous,
navigation,
searchIconVisible = false,
item,
index,
onPress
}) => {
const [dashboards, dispatchDashboards] = useReducer(apiStateReducer, {
data: [],
isLoading: true,
isError: false,
});
const [gridView, setGridView] = useState(false);
const toggleGridView = () => {
setGridView(!gridView);
};
const [filtered, setFiltered] = useState([]);
const setLoading = () => {
const messages = dashboards.data.message.filter((item) => {
const title = item.dashboardTitle || item.dashboardName;
return title.toLowerCase();
});
setFiltered(messages);
console.log(filtered);
};
const dropShadowStyle = styles.dropShadow;
const toggleSearchVisibility = () => {
navigation.navigate('Search');
};
useEffect(() => {
console.log(abcd);
setLoading();
CognitensorEndpoints.getDashboardList({
dispatchReducer: dispatchDashboards,
});
CognitensorEndpoints.getList({
dispatchReducer: dispatchDashboards,
});
},[]);
return (
<>
<View style={styles.header}>
<View style={styles.headerLeftIcon}>
<TouchableOpacity onPress={navigation.pop}>
{previous ? (
<MaterialIcons
name="chevron-left"
size={24}
style={styles.visible}
/>
) : (
<MaterialIcons
name="chevron-left"
size={24}
style={styles.invisible}
/>
)}
</TouchableOpacity>
</View>
{filtered.map(item => (
<Text style={styles.headerText}>
{item.dashboardTitle}
</Text>
))}
<View style={styles.headerRightIconContainer}>
{searchIconVisible ? (
<TouchableOpacity
style={[styles.headerRightIcon, dropShadowStyle]}
onPress={toggleSearchVisibility}>
<MaterialIcons name="search" size={24} style={styles.visible} />
</TouchableOpacity>
) : (
<View style={styles.invisible} />
)}
</View>
</View>
</>
);
};
The error is because dashboards.data.message is undefined or null. Please re-check the data.

Too many re-renders on search API

I am new to this so I hope this is the right place to get help!
As titled, executing this code is giving me the "Too many re-renders" error on React.
I have tried going through all lines and checking my hooks repeatedly, but nothing seems to work.
I am guessing this is happening due to useEffect, so pasting the code for the relevant components below:
UseResults:
import { useEffect, useState } from 'react';
import yelp from '../api/yelp';
export default () => {
const [results, setResults] = useState([]);
const [errorMessage, setErrorMessage] = useState('');
const searchApi = async () => {
try {
const response = await yelp.get('/search', {
params: {
limit: 50,
term,
location: 'san francisco'
}
});
setResults(response.data.businesses);
} catch (err) {
setErrorMessage('Something went wrong')
}
};
useEffect(() => {
searchApi('pasta');
}, []);
return [searchApi, results, errorMessage];
}
SearchScreen:
import React, { useState } from 'react';
import { Text, StyleSheet } from 'react-native';
import { ScrollView } from 'react-native-gesture-handler';
import ResultsList from '../components/ResultsList';
import SearchBar from '../components/SearchBar';
import useResults from '../hooks/useResults';
const SearchScreen = (navigation) => {
const [term, setTerm] = useState('');
const [searchApi, results, errorMessage] = useResults();
const filterResultsByPrice = (price) => {
return results.filter(result => {
return result.price === price;
});
};
return <>
<SearchBar
term={term}
onTermChange={setTerm}
onTermSubmit={searchApi()}
/>
{errorMessage ? <Text>{errorMessage}</Text> : null}
<Text>We have found {results.length} results</Text>
<ScrollView>
<ResultsList
results={filterResultsByPrice('$')}
title="Cost Effective"
navigation={navigation}
/>
<ResultsList
results={filterResultsByPrice('$$')}
title="Bit Pricier"
navigation={navigation}
/>
<ResultsList
results={filterResultsByPrice('$$$')}
title="Big Spender"
navigation={navigation}
/>
</ScrollView>
</>
};
const styles = StyleSheet.create({});
export default SearchScreen;
ResultsList:
import React from 'react';
import { View, Text, StyleSheet, FlatList } from 'react-native';
import { TouchableOpacity } from 'react-native-gesture-handler';
import ResultsDetail from './ResultsDetail';
const ResultsList = ({ title, results, navigation }) => {
return (
<View style={styles.container} >
<Text style={styles.title}>{title}</Text>
<FlatList
horizontal
showsHorizontalScrollIndicator={false}
data={results}
keyExtractor={result => result.id}
renderItem={({ item }) => {
return (
<TouchableOpacity onPress={() => navigation.navigate('ResultsShow')}>
<ResultsDetail result={item} />
</TouchableOpacity>
)
}}
/>
</View>
);
};
const styles = StyleSheet.create({
title: {
fontSize: 18,
fontWeight: 'bold',
marginLeft: 15,
marginBottom: 5
},
container: {
marginBottom: 10
}
});
export default ResultsList;
TIA!

Why my Async method is not called from another screen using functional component in react native?

I am trying to store data in Reducers file by calling Action file from my
The login screen is implemented using function components.
I can't get the point where I was mistaken and why I can't able to call the action file from my login screen.
so please help me to fix this issue. Thanks in advance.
Here is some code of my files
Login.js
import React, { useState } from 'react';
import { View, Text, SafeAreaView, StyleSheet, Image, TouchableOpacity } from 'react-native';
import { connect } from 'react-redux';
import * as actions from '../Actions';
import { Images } from '../Helpers/imageConstants';
import { RFValue } from 'react-native-responsive-fontsize';
import {
heightPercentageToDP as hp,
widthPercentageToDP as wp,
} from 'react-native-responsive-screen';
import CheckBox from 'react-native-check-box';
import { TouchableHighlight } from 'react-native-gesture-handler';
import { InputText } from '../Components/inputText';
import { ButtonTouch } from '../Components/button';
import { SignInUser } from '../Actions/authAction';
import { showMessage } from 'react-native-flash-message';
const Login = ({ navigation }) => {
const [isCheck, ischecked] = useState(false);
const [userEmail, setUserEmail] = useState('');
const [userPassword, setUserPassword] = useState('');
const handleSubmitPress = () => {
if (!userEmail) {
showMessage({
message: 'Please Enter Your Email',
type: 'danger',
});
} else if (!userPassword) {
showMessage({
message: 'Please Enter Your Password',
type: 'danger',
});
} else {
console.log('comes in else');
SignInUser({ userEmail, userPassword });
}
};
return (
<SafeAreaView style={styles.mainContainer}>
<View style={{ flex: 1 }}>
<Image source={Images.imageLogo} style={styles.imgLogo} />
<View style={{ marginTop: 60 }}>
<InputText
Placeholder={'Email'}
PlaceholderTextcolor={'#000'}
onChangeText={(userEmail) => setUserEmail(userEmail)}
/>
</View>
<View style={{ marginTop: 20 }}>
<InputText
Placeholder={'Password'}
PlaceholderTextcolor={'#000'}
onChangeText={(userPassword) => setUserPassword(userPassword)}
SecureTextEntry={true}
/>
</View>
<View style={styles.checkPwdView}>
<CheckBox
isChecked={isCheck}
style={styles.checkVw}
rightText={'Remeber Me'}
rightTextStyle={styles.rightChekBoxText}
onClick={() => {
ischecked(!isCheck);
}}
/>
<TouchableOpacity style={styles.forgotPwdTouch}>
<Text style={styles.forgotText}> Forgot Password ?</Text>
</TouchableOpacity>
</View>
<View style={{ marginBottom: 60 }}>
<ButtonTouch onPress={handleSubmitPress} title={'Login'} />
</View>
<View style={styles.dontAcntVw}>
<TouchableHighlight>
<Text style={styles.dontAcntTxt}>Dont have an account? </Text>
</TouchableHighlight>
<TouchableOpacity>
<Text style={styles.signUpTxt}> Signup here</Text>
</TouchableOpacity>
</View>
</View>
</SafeAreaView>
);
};
export default Login;
let LoginComponent = connect(actions)(Login);
export { LoginComponent };
authAction.js
import { usersArrayData } from '../Helpers/usersArrayData';
import { LOGIN_SUCCESS } from '../Actions/type';
export const SignInUser = (email, password) => async (dispatch) => {
console.log('log :--', email, password);
var userData = { data: usersArrayData };
console.log('come inn');
usersArrayData.filter((item) => {
console.log('come inn22222', usersArrayData);
if (item.emailid === email && item.pass === password) {
console.log('userdata===>>>', userData);
return dispatch({ type: LOGIN_SUCCESS, payload: userData });
} else {
return false;
}
});
};
authReducer.js
import { LOGIN_SUCCESS } from "../Actions/type"
const INITIAL_STATE = {userData:[]}
const authReducer= (state = INITIAL_STATE, action) => {
switch (action.type) {
case LOGIN_SUCCESS:
return { ...state, userData: action.payload };
default:
return state;
}
};
export default authReducer ;
I think you may add SignInUser in object function dispatch like this
const mapDispatchToProps = {
SignInUser,
};
let LoginComponent = connect(null, mapDispatchToProps)(Login);
export { LoginComponent };

Categories

Resources