![](/img/trans.png)
[英]Implementing Google Site Search results on a different page from the search bar
[英]Pass query from Search bar to results page React
我制作了一个搜索和过滤栏,作为我在 React 中制作的应用程序的一部分。 当前的工作方式是在您键入时显示建议。 但是,如果用户只是单击提交按钮,则没有处理程序。 现在单击提交按钮将带您到一个结果页面,其中包含页面 URL 中的查询。我希望在您单击该链接时将其作为 state 传递。 然后可以在结果组件中显示该链接。 我尝试过这个,但我对 React 还很陌生,所以我们将不胜感激。
这是搜索组件:
import * as React from 'react';
import { useState } from "react";
import { Link } from "react-router-dom";
const content = [
{link: '/review/elden-ring', name: 'Elden\nRing'},
{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 " xmlns="http://www.w3.org/2000/svg" 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>
);
};
这是结果组件
import * as React from 'react';
export default function Results(props) {
return (
<h1>{props.location.state.query}</h1>
);
};
航线
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 />
</>
);
};
搜索组件导入第30行
import * as React from 'react';
import Search from './search';
import { useState } from 'react';
import { Link } from 'react-router-dom';
export default function Header() {
//State to toggle navlinks on small screens
const [state, setState] = useState(false)
return (
<nav className=" w-full bg-red-500 shadow-lg relative max-h-[4.1rem]"> {/* Max height set to avoid search suggestions increasing header size */}
<div className="flex justify-between py-3.5 w-full px-3 md:w-2/3 md:px-0 m-auto">
{/* Logo */}
<Link className="text-2xl font-semibold text-white hover:animate-pulse whitespace-nowrap" to="/">GAME REVIEWS</Link>
<div className="flex max-h-[3rem]"> {/* Container to prevent flex effecting both parents container */}
{/* Links */}
{!state && (
<ul id="links" className=" h-40 lg:h-auto flex-col flex lg:flex-row absolute lg:relative mt-10 lg:mt-0 right-0 lg:right-auto px-10 lg:px-0 bg-red-500 rounded-lg lg:rounded-none shadow-sm lg:shadow-none">
<li className="m-5 lg:my-0 lg:mx-5">
<Link className="text-2xl text-white border-none hover:border-solid border-b-2 border-white" to="/">Home</Link>
</li>
<li className="m-5 lg:my-0 lg:mx-5">
<Link className="text-2xl text-white border-none hover:border-solid border-b-2 border-white" to="/reviews">Reviews</Link>
</li>
</ul>
)}
{/* Search bar */}
<Search />
{/* Hamburger */}
<div id="hamburger" onClick={() => setState(!state)} className=" space-y-2 ml-5 mt-2 block cursor-pointer lg:hidden">
<div className="w-6 h-0.5 bg-white"></div>
<div className="w-6 h-0.5 bg-white"></div>
<div className="w-6 h-0.5 bg-white"></div>
</div>
</div>
</div>
</nav>
)
}
这是我想要实现的用户搜索“游戏”的示例
单击右侧的图标后,他们应该被重定向到我的结果页面。 此页面应显示他们刚刚在提交时输入的内容。
如果您希望共享页面结果,则必须在 url 中包含搜索词,例如: www.yourdomain.com/review/elden-ring
看一看,您会发现我已经定义了review
路线现在需要一个参数。 您应该使用该参数来检查您需要在页面上显示的所有数据。
并且必须编辑搜索组件,因为您使用class
而不是className
进行样式设置。
在Results
组件上,我使用useParams
挂钩获取 url 参数并将其显示在h1
上。 您应该使用此参数作为键来检索您的 API 评论的实际详细信息。
这就是我要做的(所有逻辑):
在 App 组件上,我定义了路由:
<Routes>
<Route exact path="/" element={<Search />} />
<Route path="/review/:query" element={<Results />} />
</Routes>
在搜索组件上:
// 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
</>
)
在结果组件上:
const params = useParams(); // This retrieves all the params defined for the url
<h1>{params.query}</h1>
您可以在 URL 中传递query
的Link
组件中使用动态路由。要在Result
组件中解析它,您可以使用match
道具。
要导航,请将您的Link
组件更改为
<Link to={"/results/" + query} />
并解析Result
组件中的query
,使用
<h1>{props.match.params.id}</>
您在history.push()
方法中发送的query
必须是object
。 相反,您发送的是一个字符串。 如下所示将其更改为 object
props.history.push({
pathname: '/results',
state: { query }
});
对于以下路线。 本地主机:3000/搜索/?查询= ABCD
以下加载代码从 query=ABCD 中提取 ABCD 并设置为 state。
export default function App() {
const [query, setQuery] = useState(() => {
const q = new URLSearchParams(window.location.search);
console.log(q.toString());
return q.get("query") || "";
});
return (
<div className="App">
<h1>Query</h1>
<h2>{query}</h2>
</div>
);
}
因此,您可以通过这种方式从路线中提取信息。
现在如果你想知道如何从一页移动到另一页
假设您正在使用一些路由库,看看如何更改路由
history.push(`/search/?query={query}`)
是一种与反应路由器一起使用的方法(确保你使用 useHistory 钩子)
它比我想象的要简单得多,而且我在另一个页面上做了一些事情
为输入创建一个 state。 将输入设置为 state(查询)中的变量。 使用按钮上的 onClick 将值设置为输入。 然后该链接提供了带有路由的 state 变量。
const [query, setQuery] = useState("");
<form
className="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"
className="focus:outline-none"
type="text"
placeholder="Search"
value={query}
onChange={(event) => {
setQuery(event.target.value);
}}
/>
{/* Flex container to align the icon and bar */}
<div className="flex mt-1.5">
<Link to={{ pathname: "/results/" + query }}>
<button type="submit" onClick={() => setQuery(() => "")}>
<svg
className="fill-current h-auto w-4 "
xmlns="http://www.w3.org/2000/svg"
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>
然后在路由中路径被赋予一个变量(id)
<Route path="/results/:id" element={<Results />} />
然后可以通过 useParams 将其拉入结果页面。 并分配给我的 h1 标签。
import { useParams } from "react-router-dom";
export default function Results(props) {
const {id} = useParams();
return (
<h1>{id}</h1>
);
};
感谢大家的帮助和指导。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.