Next.JS 使用 router.push() 路由到动态页面无法正确渲染

问题描述 投票:0回答:1

我试图通过在搜索栏组件中输入搜索字符串来路由到 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} 时,页面将使用布局渲染。

html typescript next.js routes
1个回答
0
投票

首先,

你使用

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...
© www.soinside.com 2019 - 2024. All rights reserved.