Not sure how to include function in useEffect - javascript

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.

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()
}

React Navigation not passing props

I have a component that takes an object and passes it to a new screen upon navigating to the screen. However, when I go to the next screen the object passed is undefined. What am I doing wrong here? I have done the exact same thing with another component and it works perfectly fine, but on this component, it isn't passing the parameter properly. Is there something else I need to configure in the navigator?
GoalCard.JS
import * as React from 'react';
import 'react-native-get-random-values';
import { v4 as uuidv4 } from 'uuid';
import { useNavigation } from "#react-navigation/core";
import { Card, Chip, Divider, Paragraph, Text, Title } from 'react-native-paper';
const GoalCard = ({ item }) => {
const navigation = useNavigation();
const goals = JSON.parse(item.Goals);
const tasks = JSON.parse(item.GoalTasks);
const [goalsData, setGoalsData] = React.useState(
{
GoalName: item.GoalName,
GoalID: item.GoalID,
GoalDescription: item.GoalDescription,
GoalComplete: item.GoalComplete,
GoalTasks: tasks,
Goals: goals,
UserID: item.UserID,
createdAt: item.createdAt,
updatedAt: item.updatedAt
}
);
return(
<Card className="card">
<Card.Content>
<Title>Goal Set: {item.GoalName}</Title>
<Divider/>
<Paragraph>
<Chip
onPress={() => {
navigation.navigate(
'Goals', {
goalsData: goalsData
});
}}
>
Edit
</Chip>
<Text onPress={() => console.log(goalsData)}>Log</Text>
<Text>Description: {item.GoalDescription}</Text>
<Divider/>
{Object.entries(goals).map(obj => (
<Text key={uuidv4()}>{obj[1].goal}{" "}</Text>
))}
</Paragraph>
</Card.Content>
</Card>
);
}
export default GoalCard;
GoalScreen.js
Pressing "Log" as seen in this file returns undefined
import React from "react";
import { ScrollView, View } from "react-native";
import { Text } from "react-native-paper";
import { MainStyles } from "../../styles/Styles";
const GoalScreen = ({ route }) => {
const { goalData } = route.params;
return (
<ScrollView>
<View style={MainStyles.col}>
<Text onPress={() => console.log(goalData)}>Log</Text>
</View>
</ScrollView>
);
};
export default GoalScreen;
There is a typo ... You are setting
goalsData: goalsData
But you are trying to read as below
const { goalData } = route.params;
try
const { goalsData } = route.params;

React native app crashes on logout for first launch

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

Not sure how to map variable to show in app

Here's the function-
const setLoading = (value) => {
const messages = dashboards.data.message.filter((item) => {
const title = item.dashboardTitle || item.dashboardName;
return title.toLowerCase().startsWith(value.toLowerCase());
});
setFiltered(messages);
console.log(filtered);
};
I want to display the variable 'messages' separately in my app, how would I do that? 'messages' variable needs to be displayed within the default react native 'Text' component. I have written down 'messages' below within Text component but currently it's not displaying anything (since it is within function) -
import React, { useState, useEffect, useReducer } from 'react';
import { View, Text, StyleSheet, FlatList, ActivityIndicator, Keyboard} 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';
const AppHeader = ({
scene,
previous,
navigation,
searchIconVisible = false,
}) => {
const [dashboards, dispatchDashboards] = useReducer(apiStateReducer, {
data: [],
isLoading: true,
isError: false,
});
const [filtered, setFiltered] = useState([]);
const setLoading = (value) => {
const messages = dashboards.data.message.filter((item) => {
const title = item.dashboardTitle || item.dashboardName;
return title.toLowerCase().startsWith(value.toLowerCase());
});
setFiltered(messages);
console.log(filtered);
};
const dropShadowStyle = styles.dropShadow;
const toggleSearchVisibility = () => {
navigation.navigate('Search');
};
useEffect(() => {
CognitensorEndpoints.getDashboardList({
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>
<Text style={styles.headerText}>
{messages}
</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>
</>
);
};
If your messages variable is an array you can map it
{messages.map((message, key)=>(
<Text style={styles.headerText}>
{message.dashboardName}
</Text>
))}
Since your messages variable is stored in 'filtered' state, you can map it by doing this:
{filtered.map((item, index) => <Text key={index}>{item.dashboardName}<Text>)}

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!

Categories

Resources