Далее. js: одна страница, которая соответствует root '/' и динамическому c маршруту '/ param' - PullRequest
2 голосов
/ 30 мая 2020

У меня есть веб-сайт как отдельная страница, на которой используется Next. js. У меня есть домашняя страница по маршруту /, на которой отображается список продуктов. Код этой страницы находится в pages/index.js. Каждый продукт имеет id, поэтому я могу перейти к нему, используя /#product-id.

Чтобы сделать его более удобным для URL, я воспроизвожу это поведение, используя product-id в качестве второго параметра в маршруте, например: /product-id.

Я просто смотрю на параметр product-id, используя useRouter():

const selectedProductId = useRouter().query['product-id']

, а затем прокручиваю до элемента с этим идентификатором, используя js:

document.getElementById(selectedProductId ).scrollIntoView()

Итак, я должен изменить имя своего скрипта с /pages/index.js на /pages/[product-id].js.

Итак, теперь маршрут /1234 работает, как ожидалось, но если я go на / Я получаю ошибку 404.

Так есть ли у кого-нибудь идея, как я могу сопоставить / и /param, используя один файл js?

Ответы [ 2 ]

2 голосов
/ 30 мая 2020

Next js имеет маршрутизацию на основе файловой системы, поэтому, если вы удалите /pages/index.js, конечно, вы получите ошибку 404. Также /pages/index.js и /pages/[product-id].js будут отображать две отдельные страницы.

Чтобы ответить на ваш вопрос, если возможно сопоставить два маршрута, такие как / и /[productId] в одном файле, используя следующий js I не думаю, что это возможно, однако аналогичные результаты могут быть достигнуты при использовании c мелкой маршрутизации для вашего варианта использования.

Поэтому для вашего варианта использования я предлагаю использовать мелкую маршрутизацию, если вы не хотите отображать то же самое на обеих страницах, чтобы получить product-id или использовать URL-адреса ha sh.

Вы можете сделать product-id параметром строки запроса и обновить его с помощью мелкой маршрутизации. Вот пример:

Keep /pages/index.js

import { useRouter } from 'next/router';

const router = useRouter()

// when want to change the productId call
router.push('/?productId=1234', undefined, { shallow: true })

// call the scrollToView inside a useEffect hook
useEffect(() => {
    const productId = router.query.productId
    // get the element using the productId above then call scrollIntoView()
})

// if using useEffect with the dependency router.query.productId, 
// when you change the productId once and scroll up and try to change to the same -
// productId again it will not scroll to view, hence not using the dependency array
// at all

Чтобы подробнее объяснить, что делает неглубокая маршрутизация,

Мелкая маршрутизация позволит изменять URL без запуска данных методы получения, т.е. getStaticProps или getServerSideProps снова. Это сделает доступными обновленный запрос и путь без изменения состояния. Подробнее об этом далее js docs .

1 голос
/ 31 мая 2020

Вариант 1. Извлеките общий код

. Вы можете извлечь компонент страницы в отдельный файл, а затем импортировать его в /pages/index.js и /pages/[product-id].js, чтобы код не дублировался.

Вариант 2: использовать экспериментальную rewrites функцию

Если у вас есть /pages/[product-id].js, вы можете показывать эту страницу, когда пользователь запрашивает /.

Вам нужно будет добавить next.config.js.

module.exports = {
  experimental: {
    async rewrites() {
      return [
        { source: "/", destination: "/[product-id]" },
      ];
    }
  }
}

Итак, когда пользователь запрашивает /, он увидит содержимое /[product-id] только с пустым идентификатором продукта.

Обратите внимание, что на данный момент перезаписать не поддерживает автоматическую визуализацию динамических c страниц, поэтому вам необходимо отключить автоматическую визуализацию для динамических c страниц .

Вы можете сделать это, добавив getServerSideProps на /pages/[product-id].js.

export async function getServerSideProps() {
  return {
    props: {},
  }
}
...