μλ νμΈμ,
μ΄μ©λ©΄ λ΄κ° λλ½ λ κ²μ΄ μμ§λ§μ΄ κΈ°λ₯μ μ¬μ©νκ³ λ€λ₯Έ νμ΄μ§λ‘ 리λλ μ
νλ©΄ μ€ν¬λ‘€μ΄ 맨 μλ‘ μ¬μ€μ λμ§ μμ§λ§ νμ΄μ§κ° μ€κ°μΌλ‘ μ€ν¬λ‘€λμ΄μ΄ λ¬Έμ κ° λ°μνλ μ΄μ λ₯Ό μκ³ μμ§λ§ JAVASCRIPT Router.pusht({pathname: '/link', scrollreset: true})
μ κ°μ νλκ·Έλ‘ μ΄λ»κ² λ μμ ν μ μμ΅λλ€.
맨 μλ‘ μ€ν¬λ‘€ν μ§ μ¬λΆλ μ¬μ©μκ° κ²°μ ν©λλ€. componentDidMount
μ ν μ μλ€κ³ μκ°ν©λλ€.
scrollreset
μ΅μ
μ΄ μμ΄μΌ νλ€λ λ° λμν©λλ€. componentDidMount
Router.push('/link').then(() => window.scrollTo(0, 0));
$ ν μλ μμ΅λλ€.
Router.push('/link').then(() => window.scrollTo(0, 0));
μ΄κ²μ΄ μ¬λ°λ₯Έ λ°©λ²μ
λλ€. μΈμ λ μ§ readme @gragland μ μΆκ°νμΈμ β€οΈ
@gralagland μκ² κ°μ¬ν©λλ€. κ·νμ μ루μ μ κ·Έλ κ² μΆμ νμ§ μμ κ² κ°μ§λ§ DRY μμΉμ μ μ§νκΈ° μν΄ κ·Έλ¬ν μ΅μ μ΄ μμΌλ©΄ μ’μ κ²μ λλ€. νμ¬λ‘μλ μ μΌν λΉ λ₯Έ ν΄κ²°μ± μ μ΄κ²μ μμ±ν λΌμ΄λΈ ν νλ¦Ώμ λ§λλ κ²μ λλ€ π
μμ°... .then()
λ₯Ό μΆκ°νλ €λ©΄ λͺ¨λ λ¨μΌ νμ΄μ§λ₯Ό κ²ν ν΄μΌ νλ€λ λ»μ
λλ€! 그건 κ·Έλ κ³ , μ λ next-routes λ₯Ό μ¬μ©νκ³ μμΌλ―λ‘ APIλ₯Ό νΈμΆνκΈ° μ μ ν€λλ₯Ό μΆκ°ν΄μΌ νλ κ²½μ° addRequestTransform
μ κ°μ΄ μ΄ μ½λλ₯Ό ν λ²λ§ μΆκ°νλ©΄ λ©λλ€.
@MBach λμ κ΅¬μ± μμμ componentDidMount
μ $ window.scrollTo(0, 0)
λ₯Ό μ°κ²°ν μλ μμ΅λλ€.
λλ μ΄ νλμ΄ λ§€μ° λλλ€λ κ²μ μμλ€κ³ λ§νκ³ μΆμ΅λλ€. κ±°μ 1λ
λμ Next.jsλ‘ νλ‘λμ
μ¬μ΄νΈλ₯Ό ꡬμΆν΄ μμ§λ§ Router.push
κ° λ§¨ μλ‘ λμκ°μ§ μλλ€λ κ²μ μ΄μ μμΌ λ°κ²¬νμ΅λλ€. μ λ νμ Router.push
κ° <Link>
μ²λΌ νλνλ€κ³ ββμκ°νμ΅λλ€.
κ·Έλ¦¬κ³ <a>
λ <Link>
μ κ°μ κΈ°λ³Έ λμμ μΌμΉμν€λ μΈ‘λ©΄μμ 보면 Router.pushμ ν΄λΉνλ λΉ SPAλ Router.push
window.location
λ₯Ό μ€μ νλ κ²μ²λΌ λ³΄μΌ μλ μμ΅λλ€. νμ΄μ§ 맨 μλ‘, μλ? κ·Έκ²μ λμκ² κΈ°λ³Έ λμμΌλ‘ λ μ΄ν΄κ° λ κ²μ
λλ€.
@gragland μλνμ§ μμ΅λλ€
μ μμ μΌλ‘ μλνλλ‘ νλ €λ©΄ λ΄μ₯λ next.js λΌμ°ν° μ΄λ²€νΈ 리μ€λ Router.events.on('routeChangeComplete', () => { window.scrollTo(0, 0); });
λ₯Ό μ¬μ©ν μ μμ΅λλ€.
ν€λμ κ°μ λͺ¨λ νμ΄μ§μμ 곡μ λλ κ΅¬μ± μμμ μ΄κ²μ λ°°μΉνκΈ°λ§ νλ©΄ λ©λλ€.
@timneutkens λͺ
λ Ήν Router.push
λ° <Link>
μ λν κΈ°λ³Έ μ€ν¬λ‘€ λμμ΄ λ€λ₯Έ μ΄μ κ° μμ΅λκΉ? κ·Έλ€μ΄ λ€λ₯΄κ² νλνλ€λ λͺ
λ°±ν λ²κ·Έμ²λΌ 보μ
λλ€.
Router.back()μ μ½μμ λ°ννμ§ μμ§λ§ λμΌν λ¬Έμ κ° μμ΅λλ€. μλμΌλ‘ μλ‘ μ€ν¬λ‘€νλ©΄ μ΄λ»κ² ν΄μΌ ν©λκΉ?
@alexsenichev @macmenak μ루μ μ μ¬μ©ν΄ λ³΄μ ¨μ΅λκΉ?
<Link href="/product/[id]" as={
/product/${item.id} } beforePopState={()=>{
window.screenTop = 0;
}}>
<a>
<h6>{item.name}</h6>
</a>
</Link>
μλ
. Link
κ΅¬μ± μμ κΈ°λ³Έ μ€ν¬λ‘€μ 맨 μλ‘ true
μ€μ νμ§λ§ Router.push
κ° μλ μ΄μ λ 무μμ
λκΉ?
λλ μ΄ λ¬Έμ λ₯Ό μ¬κ²ν ν΄μΌ νλ€κ³ μκ°νλ€.
μ£μ‘νμ§λ§ κΈ°μ¬μ νκ·Έ: @liweinan0423 @timneutkens @exogen @goldenshun
router.push()
μ κ°μ λ‘ μ€ν¬λ‘€μ 맨 μλ‘ μ΄λνλ μ΅μ
μ΄ μμΌλ©΄ μ’κ² μ§λ§ μ΄κ²μ΄ κΈ°λ³Έ μ€μ μ΄ λμ΄μλ μ λλ€κ³ μκ°ν©λλ€. μ΄λ―Έ κ·Έλ κ² νμ§ μλλ€κ³ κ°μ νλ λͺ¨λ μ¬λλ€μκ² νκΈ°μ μΈ λ³κ²½μ΄ λ κ²μ΄κΈ° λλ¬Έμ
λλ€.
@markjackson02 μ΄κ²μ΄ λΈλΌμ°μ κ° μ΄κ²μ μ²λ¦¬νλ κΈ°λ³Έ λ°©λ²μ΄κΈ° λλ¬Έμ μ΄κ²μ΄ μ΄λ»κ² μ£Όμ λ³κ²½ μ¬νμΈμ§ μ μ μμ΅λλ€. λμΌν κΈ°λ₯μ λν΄ λ κ°μ§ λ€λ₯Έ μ κ·Ό λ°©μμ΄ μλ€λ μ¬μ€μ λμνμ§ μμ΅λλ€.
κ·Έκ²μ νμ€ν νκΈ°μ μΈ λ³νμΌ κ²μ λλ€. μ¬λλ€μ μ§κΈκ³Ό κ°μ λ°©μμΌλ‘ μ±μ ꡬμΆν΄ μμΌλ©° κ·Έλ° λ°©μμΌλ‘ μλνκΈ°λ₯Ό κΈ°λν©λλ€.
λλ λ λ€ λμΌν κΈ°λ³Έ κΈ°λ₯μ μ¬μ©νλ κ²μ λ°λνμ§ μμ§λ§ λ§μ΄κ·Έλ μ΄μ λ Έλ ₯μ κ°μΉκ° μλ€κ³ μκ°νμ§ μμ΅λλ€.
μ΄μ¨λ μ΄ λ¬Έμ λ λ«ν μμΌλ―λ‘ νκ³ μΆμ λλ‘ μ λ¬Έμ λ₯Ό μ΄μ΄μΌ ν©λλ€.
@markjackson02 OMHO, μ£Όμ λ³κ²½ μ¬νμ μμ§ κ·Έλ° μμΌλ‘ μλνμ§ μλλ€λ κ²μ λλ€! μλͺ»λ νλμ μ΄λ―Έ μ΄λ£¨μ΄μ‘μ΅λλ€. κ·Έλμ μ μκ°μλ κ·Έλ κ² νλ κ²μ΄ μ’μ κ² κ°μ΅λλ€. κ·Έλ¬λ λλ λΉμ μκ² λμν©λλ€. κΈ°μ¬μλ€μ μ¬κΈ°μ κ΄μ¬μ κΈ°μΈμ΄μ§ μμ κ²μ λλ€.
@Timer @timneutkens λν Link
μ Router.push
μ νλ μ°¨μ΄μ λ¬Όλ Έμ΅λλ€. FWIW, Router.push
options
μ +1μ μΆκ°νλ©΄ μ΄μ λ²μ κ³Όμ νΈνμ±μ μ μ§ν μ μμ΅λλ€.
μ΄κ²μ μ¬μ©νμ¬ νμ΄μ§ μλ¨μΌλ‘ λΌμ°ν νκ³ μ€ν¬λ‘€ν μ μμ΅λλ€.
// route using nextjs router and scroll to the top of the page
const routeToTop = (router, ...args) => {
if(typeof window !== 'undefined') window.scrollTo(0, 0)
return router.push.apply(router, args)
}
// usage
const router = useRouter()
routeToTop(router, '/my/page')
routeToTop(router, '/articles/[slug]', `/articles/${article.slug}`)
routeToTop(router, {
pathname: '/search',
query: {q: searchQuery},
})
Btw, μ΄κ²μ Link
λμλ§νΌ μ¬μ©μ κ²½νμ΄ μ’μ§ μμ΅λλ€. λ€μ νμ΄μ§κ° λ‘λλλ λμ νμ΄μ§ μλ¨μΌλ‘ μ¦μ μ€ν¬λ‘€νκΈ° λλ¬Έμ
λλ€.
κ΄μ¬ μλ μ¬λλ€μ μν΄ μ¬κΈ°μ κ΄λ ¨ λ¬Έμ λ₯Ό μΆκ°νμ΅λλ€: https://github.com/vercel/next.js/issues/15206
FWIW, λ€μμ κ΄λ ¨ λ¬Έμ μμ 곡μ λ ν΄κ²° λ°©λ²μ λν μ μ견μ λλ€.
import { useRouter } from 'next/router';
import { useEffect } from 'react';
/**
* React hook that forces a scroll reset to a particular set of coordinates in the document
* after `next/router` finishes transitioning to a new page client side. It smoothly scrolls back to
* the top by default.
*
* <strong i="6">@see</strong> https://github.com/vercel/next.js/issues/3249
* <strong i="7">@see</strong> https://github.com/vercel/next.js/issues/15206
* <strong i="8">@see</strong> https://developer.mozilla.org/en-US/docs/Web/API/ScrollToOptions
* <strong i="9">@param</strong> {ScrollOptions} [options={}] Hook options.
* <strong i="10">@param</strong> {ScrollBehavior} [options.behavior='smooth'] Specifies whether the scrolling should animate smoothly,
* or happen instantly in a single jump.
* <strong i="11">@param</strong> {number} [options.left=0] Specifies the number of pixels along the X axis to scroll the window.
* <strong i="12">@param</strong> {number} [options.top=0] Specifies the number of pixels along the Y axis to scroll the window.
*/
function useRouterScroll({ behavior = 'smooth', left = 0, top = 0 } = {}) {
const router = useRouter();
useEffect(() => {
// Scroll to given coordinates when router finishes navigating
// This fixes an inconsistent behaviour between `<Link/>` and `next/router`
// See https://github.com/vercel/next.js/issues/3249
const handleRouteChangeComplete = () => {
window.scrollTo({ top, left, behavior });
};
router.events.on('routeChangeComplete', handleRouteChangeComplete);
// If the component is unmounted, unsubscribe from the event
return () => {
router.events.off('routeChangeComplete', handleRouteChangeComplete);
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [behavior, left, top]);
}
export default useRouterScroll;
κ΅¬μ± μμ νΈλ¦¬ μλ¨μ μ΄λκ°μμ μ¬μ©νμμμ€( _app.js
μλ).
// _app.js
function MyApp({ Component, pageProps }) {
// Make sure pages scroll to the top after we navigate to them using `next/router`
useRouterScroll();
/* ... */
}
export default MyApp;
@nfantone μ΄ νλλ μΈμ λ³κ²½λλμ? behavior, left, top
. μλ€λ‘ μλνμ§ μμ΅λλ€.
@rakeshshubhu μ΄κ²μ next/router
λ₯Ό ν΅ν νμμλ§ μν₯μ λ―ΈμΉ©λλ€.
μμ°...
.then()
λ₯Ό μΆκ°νλ €λ©΄ λͺ¨λ λ¨μΌ νμ΄μ§λ₯Ό κ²ν ν΄μΌ νλ€λ λ»μ λλ€! 그건 κ·Έλ κ³ , μ λ next-routes λ₯Ό μ¬μ©νκ³ μμΌλ―λ‘ APIλ₯Ό νΈμΆνκΈ° μ μ ν€λλ₯Ό μΆκ°ν΄μΌ νλ κ²½μ°addRequestTransform
μ κ°μ΄ μ΄ μ½λλ₯Ό ν λ²λ§ μΆκ°νλ©΄ λ©λλ€.
λΉμ μ ν νμκ° μμ΅λλ€. λμ νλμ λͺ¨λμ λ§λ€μ΄ νμν κ΅¬μ± μμλ‘ λ΄λ³΄λ λλ€. λ°λΌμ μΌλ¨ λ³κ²½μ΄ νμνλ©΄ ν κ³³μμ λ³κ²½ν΄μΌ ν©λλ€.
λν μ»΄ν¬λνΈ λ΄λΆμμ React Hooks(μ: useRouter())λ§ μ¬μ©ν μ μκΈ° λλ¬Έμ λΌμ°ν°λ₯Ό paramμΌλ‘ μ λ¬νκ³ μμμ μ μ μμ΅λλ€.
export const navigate = (event, url, router) => {
event.preventDefault();
event.stopPropagation();
// Force scrolling to top
router.push(url).then(() => window.scrollTo(0, 0));
};
κ°μ₯ μ μ©ν λκΈ
scrollreset
μ΅μ μ΄ μμ΄μΌ νλ€λ λ° λμν©λλ€.componentDidMount
Router.push('/link').then(() => window.scrollTo(0, 0));
$ ν μλ μμ΅λλ€.