Rerouting react app just displays content on same page

Advertisements

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

>Solution :

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:

function App() {
  return (
    <Router>
      <div className="App">
        <Routes>
          <Route
            path="/"
            element={(
              <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>
            )}
          />
          <Route path="/search-results/:term" element={<SearchResultsPage />} />
        </Routes>
      </div>
    </Router>
  );
}

Leave a ReplyCancel reply