I have a react native app with a search function. The search function works fine. But the problem I am facing is that after search a user can not go back anymore to the mainscreen.Even when the search field is empty.
What I have tried? I searched for reload component react native. And I found the useFocusEffect hook
useFocusEffect
That if the screen(searchfield) is not focues you can do something.
code:
SearchAnimalContext
/* eslint-disable prettier/prettier */
import React, { createContext, useCallback, useEffect, useState } from "react";
import { CategoryNavigator } from "/src/infrastructure/navigation/category.navigator";
import { fetchAnimalData } from "./animal/animal.service";
import useDebounce from "../hooks/use-debounce";
import { useFocusEffect } from "@react-navigation/native";
export const SearchAnimalContext = createContext();
export const SearchAnimalContextProvider = ({ children, navigation }) => {
const [searchAnimal, setSearchAnimal] = useState([]);
const [results, setResults] = useState([]);
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
const [input, setInput] = useState("");
const debounce = useDebounce(searchAnimal, 500);
useFocusEffect(
useCallback(() => {
// Do something when the screen is focused
return () => {
setInput("");
navigation.navigate(CategoryNavigator());
};
}, [])
);
useEffect(() => {
fetchAnimalData();
}, [debounce]);
const performSearch = async (text) => {
setLoading(true);
setError(null);
setTimeout(() => {
fetchAnimalData(text)
.then((response2) => {
setResults(response2);
setLoading(false);
})
.catch((err) => {
setLoading(false);
setError(err);
});
});
};
return (
<SearchAnimalContext.Provider
value={{
results,
setResults,
searchAnimal,
setSearchAnimal,
input,
setInput,
performSearch,
loading,
error,
}}>
{children}
</SearchAnimalContext.Provider>
);
};
Component that is using searchContext:
/* eslint-disable prettier/prettier */
import { ActivityIndicator, MD2Colors } from "react-native-paper";
import { FlatList, TouchableOpacity } from "react-native";
import React, { useContext } from "react";
import { AccordionItemsContext } from "../../../services/accordion-items.context";
import { AnimalDetailToggle } from "../../../components/general/animal-detail-toggle-view";
import { CategoryContext } from "../../../services/category/category.context";
import { CategoryInfoCard } from "../components/category-info-card.component";
import { CategoryNavigator } from "/src/infrastructure/navigation/category.navigator";
import { SafeArea } from "../../../components/utility/safe-area.component";
import { SearchAnimalContext } from "../../../services/search-animal.context";
import { Searchbar } from "react-native-paper";
import { Spacer } from "../../../components/spacer/spacer.component";
import styled from "styled-components/native";
export const CategoryList = styled(FlatList).attrs({
contentContainerStyle: {
padding: 15,
},
})``;
export const LoadingContainer = styled.View`
position: absolute;
top: 50%;
left: 50%;
`;
export const CategoryScreen = ({ navigation }) => {
useContext(AccordionItemsContext);
const { loading, categoryList } = useContext(CategoryContext);
const { performSearch, results, setInput, input } = useContext(SearchAnimalContext);
return (
<SafeArea>
{loading && (
<LoadingContainer>
<ActivityIndicator animating={true} color={MD2Colors.blue500} />
</LoadingContainer>
)}
<Searchbar
placeholder="search animalll"
onChangeText={(text) => {
if (text.length === 0) {
navigation.navigate("Dieren");
}
setInput(text.substring(0));
performSearch(text);
}}
value={input}
/>
</SafeArea>
);
};
And the main screen has a button Dieren
<Tab.Navigator screenOptions={createScreenOptions}>
<Tab.Screen name="Dieren" component={CategoryNavigator} />
</Tab.Navigator>
And CategoryNavigator looks:
/* eslint-disable prettier/prettier */
import { createStackNavigator } from "@react-navigation/stack";
import { CategoryScreen } from "../../features/animalGroup/screens/category.screen";
import React from "react";
import { SubCategoryScreen } from "../../features/animalGroup/screens/category-sub.screen";
const CategoryStack = createStackNavigator();
export const CategoryNavigator = () => {
return (
<CategoryStack.Navigator screenOptions={{ headerShown: false }}>
<CategoryStack.Screen name="dieren" component={CategoryScreen} />
<CategoryStack.Screen name="groepen" component={SubCategoryScreen} />
</CategoryStack.Navigator>
);
};
Question: how to go back to CategoryNavigator when searchfield is empty?