So I am making a react web app and the main page has a search bar function. I want the user to enter a search result and when they click on ‘search’ they should be redirected to a new page (component) that displays details about their specific search.
However currently when the user clicks search the content that is supposed to be on a new page is just displayed underneath the contents of the main page.
Here is the code for my App.js file:
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import logo from './logo.svg';
import './App.css';
import SearchBar from './ui-components/SearchBarNew';
import PlanDisplay from './ui-components/planDisplay';
import React, { useState } from 'react';
import { withAuthenticator } from '@aws-amplify/ui-react';
import SearchResultsPage from './SearchResultsPage';
function App() {
return (
<Router>
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<SearchBar />
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
<Routes>
<Route path="/search-results/:term" element={<SearchResultsPage />} />
</Routes>
</div>
</Router>
);
}
export default withAuthenticator(App);
And here is the code for the SearchBar component that is supposed to redirect the user to a component called SearchResultsPage.jsx
import React, { useState, useCallback, useEffect } from 'react';
import { API, graphqlOperation } from 'aws-amplify';
import { useNavigate } from 'react-router-dom';
const listCourseNames = /* GraphQL */ `
query ListCourseNames {
listCourseInfos(limit: 1000) {
items {
course_name
}
}
}
`;
const SearchBar = () => {
const navigate = useNavigate();
const [searchText, setSearchText] = useState('');
const [courseNames, setCourseNames] = useState([]);
const [suggestions, setSuggestions] = useState([]);
const [selectedSuggestion, setSelectedSuggestion] = useState(null);
// Load course names from API on mount
useEffect(() => {
const fetchCourseNames = async () => {
try {
const apiKey = '****************';
const { data: { listCourseInfos: { items: courseInfoItems } } } = await API.graphql({
query: listCourseNames,
variables: {
limit: 1000,
},
headers: {
'x-api-key': apiKey,
},
});
const courseNames = courseInfoItems.map((item) => item.course_name);
setCourseNames(courseNames);
console.log(`Retrieved ${courseNames.length} course names from API`);
} catch (error) {
console.error('Error fetching course names:', error);
}
};
fetchCourseNames();
}, []);
const handleInputChange = useCallback((event) => {
const value = event.target.value;
setSearchText(value);
const newSuggestions = courseNames.filter(name => name.toLowerCase().startsWith(value.toLowerCase())).slice(0, 5);
setSuggestions(newSuggestions);
setSelectedSuggestion(null);
}, [courseNames]);
const handleSuggestionClick = useCallback((suggestion) => {
setSearchText(suggestion);
setSelectedSuggestion(null);
}, []);
const handleSubmit = useCallback((event) => {
event.preventDefault();
navigate(`/search-results/${encodeURIComponent(searchText)}`);
}, [navigate, searchText]);
return (
<div style={{ position: 'relative' }}>
<form onSubmit={handleSubmit}>
<input type="text" value={searchText} onChange={handleInputChange} />
<button type="submit">Search</button>
</form>
{suggestions.length > 0 && (
<ul style={{
position: 'absolute',
top: '100%',
left: 0,
width: '100%',
background: 'black',
boxShadow: '0px 2px 4px rgba(0,0,0,0.2)',
listStyleType: 'none',
zIndex: 1 }}>
{suggestions.map((name) => (
<li
key={name}
style={{
padding: '5px',
cursor: 'pointer',
fontSize: '14px'
}}
onClick={() => handleSuggestionClick(name)}>
{name}
</li>
))}
</ul>
)}
</div>
);
};
export default SearchBar
2
Answers
By "main page" I’m assuming everything the
App
component is rendering other than the routes is what you are calling the "main page". This content is unconditionally rendered and the routed content is rendered below it. If you want separate routes to delineate a "main" page from a "search result" page then you’ll want to move the UI content to a route as well.Example:
In it’s current state, your code consists of an App component. This component has a search bar at the top, and then a space underneath that will be filled with content depending on your current route. If I were you, I would wrap this chunk of code
into a
<Header>
component. Then, your main page will beThen, based on your question, I think you will want to make a change something like this:
Now, your app is just going to contain a single div, and then this div will contain EITHER a
<Header>
element, OR a<SearchResultsPage>
element, depending on your current URL/path.