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
useRouterbir 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-/pagesadresinden sonra gelen geçerli rota dosyasının yolu. Bu nedenle,basePath,localeve 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 vetrailingSlashyapılandırmasına uyan tarayıcıda gösterilen yol.basePathvelocaledahil 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ızcauseEffectyö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,
asPathalanının kullanılması istemci ve sunucu arasında bir uyumsuzluğa yol açabilir.isReadyalanıtrueolana kadarasPathalanı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ğertrueshallow: Geçerli sayfanın yolunu yeniden çalıştırmadan güncelleyingetStaticProps,getServerSidePropsveyagetInitialProps. Varsayılan değerfalselocale- İsteğe bağlı dize, yeni sayfanın yerel ayarını belirtir
Harici URL'ler için
router.pushkullanmanı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:
-
useEffectadresini 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
keykullanı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.replaceiç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-urliç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,urlaktif 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- Gelenpopstateolayları ü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 birpageas: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
urltarayı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.pushrouter.replacerouter.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)