我试图通过在搜索栏组件中输入搜索字符串来路由到 next.js 应用程序中动态生成的页面。 Router.push() 似乎将我路由到正确的网址,但只有在我手动刷新页面后才会呈现正确的内容。
我的搜索栏组件:
'use client'
import { useRouter } from 'next/navigation';
import { useEffect, useState } from 'react';
export const SearchBar = () => {
const [city, setCity] = useState('');
const { push } = useRouter();
useEffect(() => {
push(`/search/${city}`);
}, [city]);
return (
<div className="flex justify-center items-center mt-8">
<input
type="text"
placeholder="Search for your city"
className="w-full max-w-md p-4 rounded-l-lg shadow-lg focus:ring focus:ring-opacity-50 border-t mr-[-1px] border-b border-l border-gray-300 focus:outline-none"
value={city}
onChange={(e) => setCity(e.target.value)}
/>
<button
type="button"
className="bg-red-500 text-white px-6 py-4 rounded-r-lg shadow-lg hover:bg-red-600 transition duration-300"
onClick={() => push}
>
Search
</button>
</div>
);
};
export default SearchBar;
这是我的动态页面,位于 /app/search/[city]/page.tsx
import { Restaurant } from "@/app/_interfaces/restaurant";
import { get_restaurants_by_city } from "@/app/_utils/api.service";
import { notFound } from "next/navigation";
export default async function Page({ params }: { params: { city: string } }) {
const restaurants: Restaurant[] = await get_restaurants_by_city(params.city)
if(restaurants.length == 0){
return notFound()
}
return (
<main className="flex min-h-screen flex-col items-center justify-between p-24">
<div className="navbar">
<a href="/">Rate your favorite restaurant</a>
<a href="/regional_ratings">Leaderboard</a>
</div>
<h1>Best restaurant in {params.city}</h1>
<div className="results-container">
{restaurants.map((restaurant) => (
<div key={restaurant.id} className="result-item">
<h2>{restaurant.name} - {(restaurant.google_rating)}</h2>
<p>{restaurant.street}, {restaurant.zip_code} {restaurant.city}</p>
<p>Rating: {restaurant.google_rating}</p>
<button>Vote</button>
</div>
))
}
</div>
</main>
);
}
我猜测要么有更好的方法来路由到动态页面,要么我在这里遗漏了一些东西。
我已经尝试过redirect()函数,但无法让它正常工作,handleNavigation函数如下:
const handleNavigation = () => {
router.push(´/search/${city}´)
router.refresh()
};
这个handleNavigation 函数部分工作,但它不会加载页面及其看起来的所有html。例如,导航栏丢失了。
编辑:
通过使用这种方法:(@Dhruv 也提到过)
const handleNavigation = () => {
router.push(´/search/${city}´)
};
我被路由到正确的页面,但它不会在 /app 中渲染布局.tsx,而当手动路由到 url /search/{city_name} 时,页面将使用布局渲染。
首先,
你使用
onChange={(e) => setCity(e.target.value)}
这意味着你输入的每个字母状态都会更新,并且状态会更新然后每次使用效果都会起作用,这意味着无论路由器如何工作(哪个不工作)它都会重定向到页面,意味着你只能输入一封信,我建议你使用 onBlur 方法
onBlur={(e) => setCity(e.target.value)}
,只有在你点击任何地方的输入框后它才会起作用...
第二件事, 我认为你使用路由器的方式是错误的,我不知道,但尝试这个方法,它可能会起作用......
const [city, setCity] = useState('');
const router = useRouter(); //Instead of 'const { push } = useRouter();'
const handleSearch = () => {
if (city.trim() !== '') {
router.push(`/search/${city}`); //And then this should work i guess
}
}
//Your remaining code...