Take a look and you will see that I’ve defined that the review route now expects a parameter. You should use that parameter to check all the data you need to display on the page.
And had to edit the Search component because you’re using class instead of className for styling.
On the Results component I use the useParams hook to get the url params and show it on the h1. You should use this param as a key to retrieve the actual details of the review of your API.
// Router v6 hook to navigate the user
const navigate = useNavigate();
const queryRef = useRef(null) // Reference to the input
// Navigates the user to reviews/what they've written
const queryHandler = () => navigate(`/reviews/${queryRef.current.value}`);
return (
<>
// This is where the user types the query
<input type='text' ref={queryRef} placeholder='Search' />
<Icon onClick={queryHandler} /> // This has the onClick to hndle the click
</>
)
And on the results component:
const params = useParams(); // This retrieves all the params defined for the url
<h1>{params.query}</h1>
Solution 3 :
The query you’re sending in the history.push() method must be an object. Instead, you are sending a string. Change it to object like below
So this way you can extract the info from a route.
Now if you want to know how to move from one page to another
assuming you are using some routing library, look at how you can change the route
history.push(`/search/?query={query}`)
is a way to use with react router ( ensure you use the useHistory hook for it )
Solution 5 :
It was far simpler than I thought and something I had done on a different page
Creating a state for the input.
Setting input as the variable in that state (query).
Setting the value as the input using an onClick on the button.
The link then provided the state variable with the route.
This could then be pulled in the results page by useParams.
And assigned to my h1 tag.
import { useParams } from "react-router-dom";
export default function Results(props) {
const {id} = useParams();
return (
<h1>{id}</h1>
);
};
Thank you for everyone help and guidance.
Problem :
Ive made a search and filtering bar as part of an application im making in React. The current way it works is suggestions appear as you type. However there is no handler for if the user just clicks the submit button. At the moment clicking the submit button will take you to a results page with the query in the page URL.
I would like this to be passed as a state when you click the link. This link could then be displayed in the Results component.
Ive attempted this but im fairly new to React so any help would be appreciated.
Heres the search component:
import * as React from 'react';
import { useState } from "react";
import { Link } from "react-router-dom";
const content = [
{link: '/review/elden-ring', name: 'EldennRing'},
{link: '/review/', name: 'defg'},
{link: '/review/', name: 'ghij'},
{link: '/review/', name: 'jklm'},
]
export default function Search(props) {
//For storing and setting search input
const [query, setQuery] = useState("");
return (
//Search input
<div class="flex flex-col z-10">
<form class="text-black ml-5 py-0.5 lg:py-0 flex border-2 border-gray-400 rounded-md bg-white px-1">
<input id="searchInput" class="focus:outline-none" type="text" placeholder="Search" value={query} onChange={event => {setQuery(event.target.value)}}/>
<div class="flex mt-1.5"> {/* Flex container to align the icon and bar */}
<Link to={{pathname: "/results/" + query, state: {query}}}> {/* Error handler as search is strick */}
<button type="submit" onClick={() => setQuery(() => "")}>
<svg class="fill-current h-auto w-4 " viewBox="0 0 512 512"> {/* ! Font Awesome Pro 6.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. */}
<path d="M500.3 443.7l-119.7-119.7c27.22-40.41 40.65-90.9 33.46-144.7C401.8 87.79 326.8 13.32 235.2 1.723C99.01-15.51-15.51 99.01 1.724 235.2c11.6 91.64 86.08 166.7 177.6 178.9c53.8 7.189 104.3-6.236 144.7-33.46l119.7 119.7c15.62 15.62 40.95 15.62 56.57 0C515.9 484.7 515.9 459.3 500.3 443.7zM79.1 208c0-70.58 57.42-128 128-128s128 57.42 128 128c0 70.58-57.42 128-128 128S79.1 278.6 79.1 208z" />
</svg>
</button>
</Link>
</div>
</form>
{/* Search Suggestions */}
<div class="ml-5 px-0.5">
{/* Query must have length to prevent mapping by default */}
{query.length > 0 && content.filter((content) => {
//If input return object
if (query == "") {
return content
}
//If any input characters much object characters return corresponding object
else if (content.name.toLowerCase().includes(query.toLocaleLowerCase())) {
return content
}
})
//Maps element based on the number of json objects
.map((content) => {
return(
<div class="bg-white rounded-sm">
<Link to={content.link} onClick={() => setQuery(() => "")}><p>{content.name}</p></Link>
</div>
);
})};
</div>
</div>
);
};
Heres the Results component
import * as React from 'react';
export default function Results(props) {
return (
<h1>{props.location.state.query}</h1>
);
};
Routes
import * as React from 'react';
import './app.css';
import { Routes, Route } from "react-router-dom";
import Header from './components/header/header';
import Footer from './components/footer';
import Error from './components/error';
import Results from './components/results';
import Index from './components/index/index';
import ReviewsPage from './components/reviews/reviewsPage';
import Review from './components/reviews/review';
export default function App() {
return (
<>
<Header />
<Routes>
<Route path="/" element={<Index />} />
<Route path="/reviews" element={<ReviewsPage />} />
{/* Render review with ID for switch statment */}
<Route path="/review/:id" element={<Review />} />
<Route path="/results/:id" element={<Results />} />
<Route path="*" element={<Error />} />
</Routes>
<Footer />
</>
);
};