useRouter
Uygulamanızdaki herhangi bir işlev bileşeninin içindeki router
nesnesine erişmek istiyorsanız, useRouter
kancasını kullanabilirsiniz, aşağıdaki örneğe bir göz atın:
import { useRouter } from 'next/router'
function ActiveLink({ children, href }) {
const router = useRouter()
const style = {
marginRight: 10,
color: router.asPath === href ? 'red' : 'black',
}
const handleClick = (e) => {
e.preventDefault()
router.push(href)
}
return (
<a href={href} onClick={handleClick} style={style}>
{children}
</a>
)
}
export default ActiveLink
useRouter
bir React Hook'udur , yani sınıflarla kullanılamaz. Ya withRouter kullanabilir ya da sınıfınızı bir fonksiyon bileşenine sarabilirsiniz.
router
object
Aşağıda, her ikisi tarafından döndürülen router
nesnesinin tanımı yer almaktadır useRouter
ve withRouter
:
pathname
:String
-/pages
adresinden sonra gelen geçerli rota dosyasının yolu. Bu nedenle,basePath
,locale
ve sondaki eğik çizgi (trailingSlash: true
) dahil değildir.query
:Object
- Dinamik rota parametreleri de dahil olmak üzere bir nesneye ayrıştırılan sorgu dizesi. Sayfa Sunucu Tarafı Oluşturma kullanmıyorsa, ön oluşturma sırasında boş bir nesne olacaktır. Varsayılan değer{}
asPath
:String
- Arama parametrelerini içeren vetrailingSlash
yapılandırmasına uyan tarayıcıda gösterilen yol.basePath
velocale
dahil değildir.isFallback
:boolean
- Geçerli sayfanın geri dönüş modunda olup olmadığı.basePath
:String
- Etkin basePath (etkinleştirilmişse).locale
:String
- Etkin yerel ayar (etkinleştirilmişse).locales
:String[]
- Desteklenen tüm yerel ayarlar (etkinleştirilmişse).defaultLocale
:String
- Geçerli varsayılan yerel ayar (etkinleştirilmişse).domainLocales
:Array<{domain, defaultLocale, locales}>
- Yapılandırılmış tüm etki alanı yerelleri.isReady
:boolean
- Yönlendirici alanlarının istemci tarafında güncellenip güncellenmediği ve kullanıma hazır olup olmadığı. YalnızcauseEffect
yöntemlerinin içinde kullanılmalıdır ve sunucuda koşullu olarak işlemek için kullanılmamalıdır. Otomatik olarak statik olarak optimize edilmiş sayfalarla kullanım durumu için ilgili dokümanlara bakınisPreview
:boolean
- Uygulamanın şu anda önizleme modunda olup olmadığı.
Sayfa sunucu tarafı oluşturma veya otomatik statik optimizasyon kullanılarak oluşturulmuşsa,
asPath
alanının kullanılması istemci ve sunucu arasında bir uyumsuzluğa yol açabilir.isReady
alanıtrue
olana kadarasPath
alanını kullanmaktan kaçının.
Aşağıdaki yöntemler router
içinde yer almaktadır:
router.push
İstemci tarafı geçişlerini işler, bu yöntem aşağıdaki durumlar için kullanışlıdır next/link
yeterli değil.
router.push(url, as, options)
url
:UrlObject | String
- Gidilecek URL (UrlObject
özellikleri için Node.JS URL modülü belgesine bakın).as
:UrlObject | String
- Tarayıcı URL çubuğunda gösterilecek yol için isteğe bağlı dekoratör. Next.js 9.5.3'ten önce bu dinamik rotalar için kullanılıyordu.options
- Aşağıdaki yapılandırma seçeneklerine sahip isteğe bağlı nesne:scroll
- İsteğe bağlı boolean, gezinmeden sonra sayfanın en üstüne kaydırmayı kontrol eder. Varsayılan değertrue
shallow
: Geçerli sayfanın yolunu yeniden çalıştırmadan güncelleyingetStaticProps
,getServerSideProps
veyagetInitialProps
. Varsayılan değerfalse
locale
- İsteğe bağlı dize, yeni sayfanın yerel ayarını belirtir
Harici URL'ler için
router.push
kullanmanıza gerek yoktur. window.location bu durumlar için daha uygundur.
Önceden tanımlanmış bir rota olan pages/about.js
adresine gidiliyor:
import { useRouter } from 'next/router'
export default function Page() {
const router = useRouter()
return (
<button type="button" onClick={() => router.push('/about')}>
Click me
</button>
)
}
Dinamik bir rota olan pages/post/[pid].js
adresinde gezinme:
import { useRouter } from 'next/router'
export default function Page() {
const router = useRouter()
return (
<button type="button" onClick={() => router.push('/post/abc')}>
Click me
</button>
)
}
Kullanıcıyı pages/login.js
adresine yönlendirmek, kimlik doğrulamanın arkasındaki sayfalar için kullanışlıdır:
import { useEffect } from 'react'
import { useRouter } from 'next/router'
// Here you would fetch and return the user
const useUser = () => ({ user: null, loading: false })
export default function Page() {
const { user, loading } = useUser()
const router = useRouter()
useEffect(() => {
if (!(user || loading)) {
router.push('/login')
}
}, [user, loading])
return <p>Redirecting...</p>
}
Resetting state after navigation
Next.js'de aynı sayfaya gidildiğinde, ana bileşen değişmediği sürece React bağlantıyı kaldırmadığı için sayfanın durumu varsayılan olarak sıfırlanmayacaktır.
import Link from 'next/link'
import { useState } from 'react'
import { useRouter } from 'next/router'
export default function Page(props) {
const router = useRouter()
const [count, setCount] = useState(0)
return (
<div>
<h1>Page: {router.query.slug}</h1>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increase count</button>
<Link href="/one">one</Link> <Link href="/two">two</Link>
</div>
)
}
Yukarıdaki örnekte, /one
ve /two
arasında gezinmek sayımı sıfırlamaz. En üst düzey React bileşeni olan Page
aynı olduğu için useState
render'lar arasında korunur.
Bu davranışı istemiyorsanız, birkaç seçeneğiniz vardır:
-
useEffect
adresini kullanarak her bir durumun manuel olarak güncellendiğinden emin olun. Yukarıdaki örnekte, bu şöyle görünebilir:useEffect(() => { setCount(0) }, [router.query.slug])
-
React'e bileşenini yeniden monte etmesini söylemek için bir React
key
kullanın. Bunu tüm sayfalar için yapmak için özel bir uygulama kullanabilirsiniz:pages/_app.jsimport { useRouter } from 'next/router' export default function MyApp({ Component, pageProps }) { const router = useRouter() return <Component key={router.asPath} {...pageProps} /> }
With URL object
Bir URL nesnesini aşağıdakiler için kullanabileceğiniz şekilde kullanabilirsiniz next/link
. Hem url
hem de as
parametreleri için çalışır:
import { useRouter } from 'next/router'
export default function ReadMore({ post }) {
const router = useRouter()
return (
<button
type="button"
onClick={() => {
router.push({
pathname: '/post/[pid]',
query: { pid: post.id },
})
}}
>
Click here to read more
</button>
)
}
router.replace
replace
'daki pervaneye benzer şekilde next/link
, router.replace
history
yığınına yeni bir URL girişi eklenmesini engelleyecektir.
router.replace(url, as, options)
router.replace
için API, aşağıdakiler için API ile tamamen aynıdırrouter.push
.
Aşağıdaki örneğe bir göz atın:
import { useRouter } from 'next/router'
export default function Page() {
const router = useRouter()
return (
<button type="button" onClick={() => router.replace('/home')}>
Click me
</button>
)
}
router.prefetch
Daha hızlı istemci tarafı geçişleri için sayfaları önceden getirin. Bu yöntem, yalnızca istemci tarafında next/link
çünkü next/link
sayfaları otomatik olarak önceden getirme işlemini gerçekleştirir.
Bu yalnızca üretime yönelik bir özelliktir. Next.js geliştirme aşamasında sayfaları önceden getirmez.
router.prefetch(url, as, options)
url
- Açık rotalar (örn./dashboard
) ve dinamik rotalar (örn./product/[id]
) dahil olmak üzere, önceden getirilecek URLas
-url
için isteğe bağlı dekoratör. Next.js 9.5.3'ten önce bu dinamik rotaları önceden almak için kullanılıyordu.options
- Aşağıdaki izin verilen alanlara sahip isteğe bağlı nesne:locale
- etkin olandan farklı bir yerel ayar sağlamaya izin verir. Eğerfalse
,url
aktif yerel ayar kullanılmayacağı için yerel ayarı içermelidir.
Diyelim ki bir giriş sayfanız var ve giriş yaptıktan sonra kullanıcıyı kontrol paneline yönlendiriyorsunuz. Bu durumda, aşağıdaki örnekte olduğu gibi daha hızlı bir geçiş yapmak için gösterge tablosunu önceden getirebiliriz:
import { useCallback, useEffect } from 'react'
import { useRouter } from 'next/router'
export default function Login() {
const router = useRouter()
const handleSubmit = useCallback((e) => {
e.preventDefault()
fetch('/api/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
/* Form data */
}),
}).then((res) => {
// Do a fast client-side transition to the already prefetched dashboard page
if (res.ok) router.push('/dashboard')
})
}, [])
useEffect(() => {
// Prefetch the dashboard page
router.prefetch('/dashboard')
}, [router])
return (
<form onSubmit={handleSubmit}>
{/* Form fields */}
<button type="submit">Login</button>
</form>
)
}
router.beforePopState
Bazı durumlarda (örneğin, Özel Sunucu kullanıyorsanız), popstate adresini dinlemek ve yönlendirici buna göre hareket etmeden önce bir şeyler yapmak isteyebilirsiniz.
router.beforePopState(cb)
cb
- Gelenpopstate
olayları üzerinde çalıştırılacak işlev. İşlev, olayın durumunu aşağıdaki prop'lara sahip bir nesne olarak alır:url
:String
- yeni eyalet için rota. Bu genellikle birpage
as
:String
- tarayıcıda gösterilecek urloptions
:Object
- router.push tarafından gönderilen ek seçenekler
cb
, false
döndürürse Next.js yönlendiricisi popstate
ile ilgilenmez ve bu durumda bu işlemden siz sorumlu olursunuz. Dosya sistemi yönlendirmesini devre dışı bırakma bölümüne bakın.
İsteği değiştirmek için beforePopState
adresini kullanabilir veya aşağıdaki örnekte olduğu gibi bir SSR yenilemesini zorlayabilirsiniz:
import { useEffect } from 'react'
import { useRouter } from 'next/router'
export default function Page() {
const router = useRouter()
useEffect(() => {
router.beforePopState(({ url, as, options }) => {
// I only want to allow these two routes!
if (as !== '/' && as !== '/other') {
// Have SSR render bad routes as a 404.
window.location.href = as
return false
}
return true
})
}, [router])
return <p>Welcome to the page</p>
}
router.back
Geçmişte geri gitme. Tarayıcının geri düğmesine tıklamaya eşdeğerdir. window.history.back()
adresini çalıştırır.
import { useRouter } from 'next/router'
export default function Page() {
const router = useRouter()
return (
<button type="button" onClick={() => router.back()}>
Click here to go back
</button>
)
}
router.reload
Geçerli URL'yi yeniden yükleyin. Tarayıcının yenile düğmesine tıklamaya eşdeğerdir. window.location.reload()
adresini çalıştırır.
import { useRouter } from 'next/router'
export default function Page() {
const router = useRouter()
return (
<button type="button" onClick={() => router.reload()}>
Click here to reload
</button>
)
}
router.events
Next.js Router içinde gerçekleşen farklı olayları dinleyebilirsiniz. İşte desteklenen olayların bir listesi:
routeChangeStart(url, { shallow })
- Bir rota değişmeye başladığında ateşlenirrouteChangeComplete(url, { shallow })
- Bir rota tamamen değiştiğinde ateşlenirrouteChangeError(err, url, { shallow })
- Rotaları değiştirirken bir hata olduğunda veya bir rota yüklemesi iptal edildiğinde ateşlenirerr.cancelled
- Navigasyonun iptal edilip edilmediğini gösterir
beforeHistoryChange(url, { shallow })
- Tarayıcının geçmişini değiştirmeden önce ateşlenirhashChangeStart(url, { shallow })
- Hash değiştiğinde ancak sayfa değişmediğinde ateşlenirhashChangeComplete(url, { shallow })
- Hash değiştiğinde ancak sayfa değişmediğinde tetiklenir
Bildiğim iyi oldu: Burada
url
tarayıcıda gösterilen URL'dir.basePath
.
Örneğin, yönlendirici olayını dinlemek için routeChangeStart
, pages/_app.js
adresini açın veya oluşturun ve aşağıdaki gibi olaya abone olun:
import { useEffect } from 'react'
import { useRouter } from 'next/router'
export default function MyApp({ Component, pageProps }) {
const router = useRouter()
useEffect(() => {
const handleRouteChange = (url, { shallow }) => {
console.log(
`App is changing to ${url} ${
shallow ? 'with' : 'without'
} shallow routing`
)
}
router.events.on('routeChangeStart', handleRouteChange)
// If the component is unmounted, unsubscribe
// from the event with the `off` method:
return () => {
router.events.off('routeChangeStart', handleRouteChange)
}
}, [router])
return <Component {...pageProps} />
}
Bu örnekte olaya abone olmak için bir Özel Uygulama (
pages/_app.js
) kullanıyoruz çünkü sayfa gezintilerinde kaldırılmıyor, ancak uygulamanızdaki herhangi bir bileşendeki yönlendirici olaylarına abone olabilirsiniz.
Yönlendirici olayları, bir bileşen bağlandığında(useEffect veya componentDidMount / componentWillUnmount) veya zorunlu olarak bir olay gerçekleştiğinde kaydedilmelidir.
Bir rota yüklemesi iptal edilirse (örneğin, art arda iki bağlantıya hızlı bir şekilde tıklanarak), routeChangeError
ateşlenecektir. Ve iletilen err
, aşağıdaki örnekte olduğu gibi true
olarak ayarlanmış bir cancelled
özelliği içerecektir:
import { useEffect } from 'react'
import { useRouter } from 'next/router'
export default function MyApp({ Component, pageProps }) {
const router = useRouter()
useEffect(() => {
const handleRouteChangeError = (err, url) => {
if (err.cancelled) {
console.log(`Route to ${url} was cancelled!`)
}
}
router.events.on('routeChangeError', handleRouteChangeError)
// If the component is unmounted, unsubscribe
// from the event with the `off` method:
return () => {
router.events.off('routeChangeError', handleRouteChangeError)
}
}, [router])
return <Component {...pageProps} />
}
Potential ESLint errors
router
nesnesinde erişilebilen belirli yöntemler bir Promise döndürür. ESLint kuralı no-floating-promises etkinleştirilmişse, bunu genel olarak veya etkilenen satır için devre dışı bırakmayı düşünün.
Uygulamanızın bu kurala ihtiyacı varsa, ya void
promise'i kullanmalı ya da bir async
fonksiyonu kullanmalı, await
Promise'i kullanmalı ve ardından fonksiyon çağrısını geçersiz kılmalısınız. Bu, yöntem bir onClick
işleyicisinin içinden çağrıldığında geçerli değildir.
Etkilenen yöntemler şunlardır:
router.push
router.replace
router.prefetch
Potential solutions
import { useEffect } from 'react'
import { useRouter } from 'next/router'
// Here you would fetch and return the user
const useUser = () => ({ user: null, loading: false })
export default function Page() {
const { user, loading } = useUser()
const router = useRouter()
useEffect(() => {
// disable the linting on the next line - This is the cleanest solution
// eslint-disable-next-line no-floating-promises
router.push('/login')
// void the Promise returned by router.push
if (!(user || loading)) {
void router.push('/login')
}
// or use an async function, await the Promise, then void the function call
async function handleRouteChange() {
if (!(user || loading)) {
await router.push('/login')
}
}
void handleRouteChange()
}, [user, loading])
return <p>Redirecting...</p>
}
withRouter
Eğer useRouter
sizin için en uygunu değilse, withRouter
aynı router
nesnesini herhangi bir bileşene de ekleyebilir.
Usage
import { withRouter } from 'next/router'
function Page({ router }) {
return <p>{router.pathname}</p>
}
export default withRouter(Page)
TypeScript
Sınıf bileşenlerini withRouter
ile kullanmak için bileşenin bir yönlendirici prop kabul etmesi gerekir:
import React from 'react'
import { withRouter, NextRouter } from 'next/router'
interface WithRouterProps {
router: NextRouter
}
interface MyComponentProps extends WithRouterProps {}
class MyComponent extends React.Component<MyComponentProps> {
render() {
return <p>{this.props.router.pathname}</p>
}
}
export default withRouter(MyComponent)