Here are 3 basic components searchBar which refers to the search bar form and, the searchPage component which displays the search results, and of course, the app component which contains them all.
mechanism:
- the user submits an input in the searchBar component, the
handleSubmitfunction gets fired, which changes the state ofsetSearchedProductsto the input value, byuseContextAND getting pushed to the ("/SearchPage") byhistory.push().
import {useState, useContext } from "react";
import { useHistory } from "react-router-dom";
import { LocaleContext } from "../../../LocaleContext";
const SearchBar = () => {
const history = useHistory();
const {setSearchedTerm} = useContext(LocaleContext);
const handleSubmit = (SearchTerm) => {
setSearchedProducts(SearchTerm)
history.push("/SearchPage");
}
return (
<form>
<input onSubmit={(e) => handleSubmit(e.target.value)}>
</input>
<button type="submit">Submit</button>
</form>
)
}
export default SearchBar
- the value gets sent to the app component by react context and the state gets set to the value while still pushing to the ("/searchPage").
import { useState, useMemo } from "react";
import { searchBar, searchPage } from "./components";
import { BrowserRouter as Router, Switch, Route } from "react-router-dom";
import {LocaleContext} from "./LocaleContext"
const App = () => {
const [searchedTerm, setSearchedTerm] = useState("");
const providerValue = useMemo(() => ({searchedTerm, setSearchedTerm}),
[searchedTerm, setSearchedTerm])
return (
<Router>
<LocaleContext.Provider value={providerValue}>
<searchBar />
<Switch>
<Route exact path="/SearchPage">
<SearchPage />
</Route>
</Switch>
</LocaleContext.Provider>
</Router>
);
}
export default (App);
- displaying the searchPage component, which gets the state value
by using
useContext, and withuseEffect, thefetchProducts()function gets fired, that fetches a set of products based on the state value.
import {useState, useEffect, useContext} from 'react';
import { LocaleContext } from "../../LocaleContext";
const SearchPage = ({}) => {
const [products, setProducts] = useState([]);
const {searchedTerm} = useContext(LocaleContext);
const fetchProducts = (term) => {
setLoading(true);
const url = new URL(
"https://example/products"
);
let params = {
"query": term
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
let headers = {
"Accept": "application/json",
"Content-Type": "application/json",
};
fetch(url, {
method: "GET",
headers: headers,
})
.then(response => response.json())
.then(json => {
setProducts(json);
});
}
useEffect(() => {
fetchProducts(searchedProducts)
}, [])
return (
{
products.map(product => (
<div>
{product.name}
</div>
))
}
)
}
export default SearchPage
Issues:
- when the router changes to the ("/searchPage") component state value get lost, meaning it returns to "" value. ?
- lesser problem, if the user sends an empty string (" "), and the API needs a value or it will give an error, what is the solution to that?
- is there a way of keeping the value after reloading the page?
import {createContext} from "react";
export const LocaleContext = createContext(null);
this is the localeContext component if needed.