react-router เลื่อนขึ้นไปด้านบนในทุกการเปลี่ยนแปลง


135

ฉันมีปัญหาเมื่อไปที่หน้าอื่นตำแหน่งของมันจะยังคงเหมือนหน้าก่อน ดังนั้นจะไม่เลื่อนขึ้นไปด้านบนโดยอัตโนมัติ ฉันพยายามใช้window.scrollTo(0, 0)กับonChangeเราเตอร์ด้วย ฉันเคยscrollBehaviorแก้ไขปัญหานี้ด้วย แต่ไม่ได้ผล ข้อเสนอแนะเกี่ยวกับเรื่องนี้หรือไม่?


คุณไม่สามารถใช้ตรรกะในcomponentDidMountองค์ประกอบของเส้นทางใหม่ได้หรือไม่?
Yuya

เพียงแค่เพิ่มdocument.body.scrollTop = 0;ในcomponentDidMountองค์ประกอบที่คุณกำลังจะย้ายไป
จอห์นรัดเดลล์

@Kujira ฉันได้เพิ่ม scrollTo ภายใน componentDidMount () แล้ว แต่มันไม่ได้ผล
adrian hartanto

@JohnRuddell นั่นก็ไม่ได้ผลเช่นกัน
adrian hartanto

ฉันต้องใช้ document.getElementById ('root') scrollTop = 0 จึงจะทำงานได้
นาย 14

คำตอบ:


138

เอกสารสำหรับ React Router v4 มีตัวอย่างโค้ดสำหรับการคืนค่าการเลื่อน นี่คือตัวอย่างโค้ดแรกซึ่งทำหน้าที่เป็นโซลูชันทั่วทั้งไซต์สำหรับ "เลื่อนไปด้านบน" เมื่อหน้าถูกไปที่:

class ScrollToTop extends Component {
  componentDidUpdate(prevProps) {
    if (this.props.location !== prevProps.location) {
      window.scrollTo(0, 0)
    }
  }

  render() {
    return this.props.children
  }
}

export default withRouter(ScrollToTop)

จากนั้นแสดงผลที่ด้านบนสุดของแอป แต่ด้านล่างเราเตอร์:

const App = () => (
  <Router>
    <ScrollToTop>
      <App/>
    </ScrollToTop>
  </Router>
)

// or just render it bare anywhere you want, but just one :)
<ScrollToTop/>

^ คัดลอกโดยตรงจากเอกสารประกอบ

เห็นได้ชัดว่าสิ่งนี้ใช้ได้กับกรณีส่วนใหญ่ แต่มีวิธีจัดการกับอินเทอร์เฟซแบบแท็บมากขึ้นและเหตุใดจึงไม่มีการนำโซลูชันทั่วไปมาใช้


3
คุณควรรีเซ็ตโฟกัสของแป้นพิมพ์ในเวลาเดียวกันกับการเลื่อนไปด้านบน ฉันเขียนสิ่งที่ต้องดูแล: github.com/oaf-project/oaf-react-router
danielnixon

3
สารสกัดจากเอกสารนี้Because browsers are starting to handle the “default case” and apps have varying scrolling needs (like this website!), we don’t ship with default scroll management. This guide should help you implement whatever scrolling needs you have.ทำให้ฉันเสียใจเพราะตัวเลือกทั้งหมดที่พวกเขาใช้เพื่อยกตัวอย่างโค้ดนั้นสามารถถูกรวมเข้ากับการควบคุมผ่านการตั้งค่าคุณสมบัติโดยมีข้อตกลงบางประการเกี่ยวกับพฤติกรรมเริ่มต้นที่สามารถเปลี่ยนแปลงได้ นี่รู้สึกแฮ็กสุด ๆ และยังไม่เสร็จ imho หมายความว่าเฉพาะนักพัฒนาตอบสนองขั้นสูงเท่านั้นที่สามารถกำหนดเส้นทางได้อย่างถูกต้องและไม่มี #pitOfSuccess
snowcode

2
oaf-react-router ดูเหมือนจะแก้ไขปัญหาการเข้าถึงที่สำคัญซึ่งทั้งหมดwork-aroundsนี้ได้เพิกเฉย +100 สำหรับ @danielnixon
snowcode

ไม่ได้กำหนด ScrollToTop จะนำเข้าใน App.js ได้อย่างไร? นำเข้า ScrollToTop จาก "./ScrollToTop" ไม่ทำงาน
anhtv13

@ anhtv13 คุณควรถามเป็นคำถามใหม่เพื่อที่คุณจะได้ใส่รหัสที่คุณกำลังอ้างอิง
mtl

123

แต่ชั้นเรียนเป็นปี 2018

การใช้งาน ScrollToTop กับ React Hooks

ScrollToTop.js

import { useEffect } from 'react';
import { withRouter } from 'react-router-dom';

function ScrollToTop({ history }) {
  useEffect(() => {
    const unlisten = history.listen(() => {
      window.scrollTo(0, 0);
    });
    return () => {
      unlisten();
    }
  }, []);

  return (null);
}

export default withRouter(ScrollToTop);

การใช้งาน:

<Router>
  <Fragment>
    <ScrollToTop />
    <Switch>
        <Route path="/" exact component={Home} />
    </Switch>
  </Fragment>
</Router>

ScrollToTop สามารถนำไปใช้เป็นส่วนประกอบของ Wrapper:

ScrollToTop.js

import React, { useEffect, Fragment } from 'react';
import { withRouter } from 'react-router-dom';

function ScrollToTop({ history, children }) {
  useEffect(() => {
    const unlisten = history.listen(() => {
      window.scrollTo(0, 0);
    });
    return () => {
      unlisten();
    }
  }, []);

  return <Fragment>{children}</Fragment>;
}

export default withRouter(ScrollToTop);

การใช้งาน:

<Router>
  <ScrollToTop>
    <Switch>
        <Route path="/" exact component={Home} />
    </Switch>
  </ScrollToTop>
</Router>

3
ทางออกที่ดีที่สุดที่ฉันเคยเห็นบนอินเทอร์เน็ต ฉันเพียงเล็กน้อยสับสนว่าทำไมโครงการตอบสนองเราเตอร์ไม่เพิ่มคุณสมบัติในการscrollToTop <Route>ดูเหมือนว่าจะเป็นคุณสมบัติที่ใช้บ่อยมาก
stanleyxu2005

ทำได้ดีมากครับ ช่วยได้เยอะเลย
VaibS

วิธีใดเป็นวิธีที่เหมาะสมในการทดสอบหน่วยนี้
Matt

action !== 'POP'คุณควรตรวจสอบ ผู้ฟังยอมรับการกระทำเป็นอาร์กิวเมนต์ที่ 2
Atombit

2
นอกจากนี้คุณสามารถใช้ useHistory hook แทน withRouter HOC
Atombit

30

คำตอบนี้ใช้สำหรับรหัสเดิมสำหรับเราเตอร์ v4 + ตรวจสอบคำตอบอื่น ๆ

<Router onUpdate={() => window.scrollTo(0, 0)} history={createBrowserHistory()}>
  ...
</Router>

หากยังไม่ได้ผลคุณควรหาเหตุผล นอกจากนี้ภายในcomponentDidMount

document.body.scrollTop = 0;
// or
window.scrollTo(0,0);

คุณสามารถใช้:

componentDidUpdate() {
  window.scrollTo(0,0);
}

คุณสามารถเพิ่มค่าสถานะบางอย่างเช่น "scrolled = false" จากนั้นในการอัปเดต:

componentDidUpdate() {
  if(this.scrolled === false){
    window.scrollTo(0,0);
    scrolled = true;
  }
}

ฉันได้อัปเดตคำตอบโดยไม่มี getDomNode เลยเพราะอันที่จริงฉันไม่ต้องใช้มันเพื่อเลื่อนไปด้านบน ฉันเพิ่งใช้window.scrollTo(0,0);
Lukas Liesis

3
onUpdatehook เลิกใช้งานใน react-router v4 - แค่อยากจะชี้ให้เห็น
Dragos Rizescu

@DragosRizescu คำแนะนำใด ๆ เกี่ยวกับการใช้วิธีนี้โดยไม่ต้องใช้onUpdateตะขอ?
Matt Voda

1
@MattVoda คุณสามารถฟังการเปลี่ยนแปลงในประวัติศาสตร์ได้ตรวจสอบตัวอย่าง: github.com/ReactTraining/history
Lukas Liesis

3
@MattVoda เขียนคำตอบไว้ด้านล่างว่าคุณจะทำมันได้อย่างไรด้วย react-router-v4
Dragos Rizescu

28

สำหรับreact-router v4นี่คือแอป create-react-ที่สามารถกู้คืนการเลื่อนได้: http://router-scroll-top.surge.sh/ http://router-scroll-top.surge.sh/

เพื่อให้บรรลุสิ่งนี้คุณสามารถสร้างการตกแต่งRouteส่วนประกอบและใช้ประโยชน์จากวิธีการวงจรชีวิต:

import React, { Component } from 'react';
import { Route, withRouter } from 'react-router-dom';

class ScrollToTopRoute extends Component {
  componentDidUpdate(prevProps) {
    if (this.props.path === this.props.location.pathname && this.props.location.pathname !== prevProps.location.pathname) {
      window.scrollTo(0, 0)
    }
  }

  render() {
    const { component: Component, ...rest } = this.props;

    return <Route {...rest} render={props => (<Component {...props} />)} />;
  }
}

export default withRouter(ScrollToTopRoute);

ในการcomponentDidUpdateตรวจสอบเราสามารถตรวจสอบเมื่อชื่อพา ธ สถานที่เปลี่ยนไปและจับคู่กับpathเสาและหากพอใจให้เรียกคืนการเลื่อนหน้าต่าง

สิ่งที่ยอดเยี่ยมเกี่ยวกับแนวทางนี้คือเราสามารถมีเส้นทางที่เรียกคืนการเลื่อนและเส้นทางที่ไม่คืนค่าการเลื่อน

นี่คือApp.jsตัวอย่างวิธีการใช้งานด้านบน:

import React, { Component } from 'react';
import { BrowserRouter as Router, Route, Link } from 'react-router-dom';
import Lorem from 'react-lorem-component';
import ScrollToTopRoute from './ScrollToTopRoute';
import './App.css';

const Home = () => (
  <div className="App-page">
    <h2>Home</h2>
    <Lorem count={12} seed={12} />
  </div>
);

const About = () => (
  <div className="App-page">
    <h2>About</h2>
    <Lorem count={30} seed={4} />
  </div>
);

const AnotherPage = () => (
  <div className="App-page">
    <h2>This is just Another Page</h2>
    <Lorem count={12} seed={45} />
  </div>
);

class App extends Component {
  render() {
    return (
      <Router>
        <div className="App">
          <div className="App-header">
            <ul className="App-nav">
              <li><Link to="/">Home</Link></li>
              <li><Link to="/about">About</Link></li>
              <li><Link to="/another-page">Another Page</Link></li>
            </ul>
          </div>
          <Route exact path="/" component={Home} />
          <ScrollToTopRoute path="/about" component={About} />
          <ScrollToTopRoute path="/another-page" component={AnotherPage} />
        </div>
      </Router>
    );
  }
}

export default App;

จากโค้ดด้านบนสิ่งที่น่าสนใจที่จะชี้ให้เห็นก็คือเมื่อนำทางไปยัง/aboutหรือ/another-pageเลื่อนไปที่การกระทำด้านบนเท่านั้นที่จะถูกสร้างไว้ล่วงหน้า อย่างไรก็ตามเมื่อเกิดขึ้น/ไม่มีการเรียกคืนการเลื่อนเกิดขึ้น

คุณสามารถดูโค้ดเบสทั้งหมดได้ที่นี่: https://github.com/rizedr/react-router-scroll-top


1
สิ่งที่ฉันกำลังมองหา! ฉันต้องเพิ่ม scrollTo ใน componentDidMount ของ ScrollToTopRoute เนื่องจากฉันมีเส้นทางของฉันที่ห่อหุ้มไว้ในส่วนประกอบ Switch (ฉันยังลบถ้าตามที่ฉันต้องการให้มันยิงในแต่ละเมาท์)
tocallaghan

ในการแสดง ScrollToTopRoute คุณไม่จำเป็นต้องระบุ render = {props => (<Component {... props} />)} เพียงใช้ {... rest} ในเส้นทางก็จะได้ผล
Finickyflame

คำตอบนี้ทำให้ฉันมีเครื่องมือทั้งหมดในการแก้ปัญหาและแก้ไขข้อบกพร่องของฉัน ขอบคุณมาก.
Null isTrue

มันทำงานไม่สมบูรณ์ หากคุณไปตามลิงค์โครงการจะเป็นค่าเริ่มต้นเปิดไฟล์Home. ตอนนี้เลื่อนไปที่ด้านล่างของHomeและไปที่ 'AnotherPage' แล้วอย่าเลื่อน ตอนนี้ถ้าคุณกลับมาอีกครั้งHomeหน้านี้จะเลื่อนไปด้านบน แต่ตามคำตอบของคุณhomeควรเลื่อนหน้าต่อไป
aditya81070

21

หากคุณใช้ React 16.8+ สิ่งนี้จะตรงไปตรงมาในการจัดการกับคอมโพเนนต์ที่จะเลื่อนหน้าต่างขึ้นทุกการนำทาง:
นี่คือองค์ประกอบ scrollToTop.js

import { useEffect } from "react";
import { useLocation } from "react-router-dom";

export default function ScrollToTop() {
  const { pathname } = useLocation();

  useEffect(() => {
    window.scrollTo(0, 0);
  }, [pathname]);

  return null;
}

จากนั้นแสดงผลที่ด้านบนสุดของแอป แต่ด้านล่าง Router
Here อยู่ใน app.js

import ScrollToTop from "./scrollToTop";

function App() {
  return (
    <Router>
      <ScrollToTop />
      <App />
    </Router>
  );
}

หรือใน index.js

import ScrollToTop from "./scrollToTop";

ReactDOM.render(
    <BrowserRouter>
        <ScrollToTop />
        <App />
    </BrowserRouter>
    document.getElementById("root")
);

18

เป็นที่สังเกตได้ว่าonUpdate={() => window.scrollTo(0, 0)}วิธีนี้ล้าสมัย

นี่คือวิธีง่ายๆสำหรับ react-router 4+

const history = createBrowserHistory()

history.listen(_ => {
    window.scrollTo(0, 0)  
})

<Router history={history}>

นี่ควรเป็นคำตอบที่ถูกต้องหากใช้ประวัติศาสตร์ ครอบคลุมเนื้อหาในท้ายที่สุดทั้งหมดรวมถึงการคลิกลิงก์ไปยังหน้าที่คุณกำลังเปิดอยู่ ปัญหาเดียวที่ฉันพบคือ scrollTo ไม่เริ่มทำงานและจำเป็นต้องรวมไว้ใน setTimeout (window.scrollTo (0, 0), 0); ฉันยังไม่เข้าใจว่าทำไม แต่เดี๋ยวก่อน
sidonaldson

4
คุณจะมีปัญหาเมื่อคุณเพิ่ม#และ?ต่อท้าย url ของเรา ในกรณีแรกคุณควรเลื่อนไม่ขึ้นไปด้านบนในกรณีที่สองคุณไม่ควรเลื่อนเลย
Arseniy-II

1
ขออภัยสิ่งนี้ใช้ไม่ได้กับ BrowserRouter
VaibS

14

React Hook ที่คุณสามารถเพิ่มเข้าไปในองค์ประกอบเส้นทางของคุณ ใช้useLayoutEffectแทนผู้ฟังที่กำหนดเอง

import React, { useLayoutEffect } from 'react';
import { Switch, Route, useLocation } from 'react-router-dom';

export default function Routes() {
  const location = useLocation();
  // Scroll to top if path changes
  useLayoutEffect(() => {
    window.scrollTo(0, 0);
  }, [location.pathname]);

  return (
      <Switch>
        <Route exact path="/">

        </Route>
      </Switch>
  );
}

อัปเดต : อัปเดตเพื่อใช้useLayoutEffectแทนuseEffectสำหรับการมองเห็นน้อยลง โดยประมาณนี้แปลว่า:

  • useEffect: render components -> paint to screen -> scroll to top (run effect)
  • useLayoutEffect: แสดงส่วนประกอบ -> เลื่อนไปด้านบน (เรียกใช้เอฟเฟกต์) -> ระบายสีไปที่หน้าจอ

ขึ้นอยู่กับว่าคุณกำลังโหลดข้อมูล (คิดว่าสปินเนอร์) หรือหากคุณมีภาพเคลื่อนไหวการเปลี่ยนหน้าuseEffectอาจจะเหมาะกับคุณ


7

ฉันมีปัญหาเดียวกันกับแอปพลิเคชันของฉันการใช้ข้อมูลโค้ดด้านล่างช่วยให้ฉันเลื่อนไปที่ด้านบนของหน้าเมื่อคลิกปุ่มถัดไป

<Router onUpdate={() => window.scrollTo(0, 0)} history= {browserHistory}>
...
</Router>

อย่างไรก็ตามปัญหายังคงมีอยู่ในเบราว์เซอร์กลับ หลังจากการทดลองหลายครั้งพบว่านี่เป็นเพราะวัตถุประวัติของหน้าต่างเบราว์เซอร์ซึ่งมีคุณสมบัติ scrollRestoration ซึ่งตั้งค่าเป็นอัตโนมัติการตั้งค่านี้เป็นแบบแมนนวลช่วยแก้ปัญหาของฉันได้

function scrollToTop() {
    window.scrollTo(0, 0)
    if ('scrollRestoration' in history) {
        history.scrollRestoration = 'manual';
    }
}

<Router onUpdate= {scrollToTop} history={browserHistory}>
....
</Router>

7

ในส่วนประกอบด้านล่าง <Router>

เพียงเพิ่ม React Hook (ในกรณีที่คุณไม่ได้ใช้คลาส React)

  React.useEffect(() => {
    window.scrollTo(0, 0);
  }, [props.location]);

6

React hooks 2020 :)

import React, { useLayoutEffect } from 'react';
import { useLocation } from 'react-router-dom';

const ScrollToTop: React.FC = () => {
  const { pathname } = useLocation();
  useLayoutEffect(() => {
    window.scrollTo(0, 0);
  }, [pathname]);

  return null;
};

export default ScrollToTop;

คุณช่วยอธิบายส่วนนี้ได้ไหม const ScrollToTop: React.FC = () => {ฉันไม่เข้าใจว่าScrollToTop: React.FCหมายถึงอะไร
beeftosino

1
typescript definition
Kepro

5

ฉันต้องการแบ่งปันวิธีแก้ปัญหาของฉันสำหรับผู้ที่ใช้react-router-dom v5เนื่องจากโซลูชัน v4 เหล่านี้ไม่ได้ผลสำหรับฉัน

สิ่งที่แก้ปัญหาของฉันได้คือการติดตั้งreact-router-scroll-topและใส่ wrapper ใน<App />ลักษณะนี้:

const App = () => (
  <Router>
    <ScrollToTop>
      <App/>
    </ScrollToTop>
  </Router>
)

เท่านี้เอง! มันได้ผล!


5

ตะขอสามารถประกอบได้และตั้งแต่ React Router v5.1 เราจึงมีuseHistory()ตะขอ จากคำตอบของ @ zurfyx ฉันได้สร้างเบ็ดที่ใช้ซ้ำได้สำหรับฟังก์ชันนี้:

// useScrollTop.ts
import { useHistory } from 'react-router-dom';
import { useEffect } from 'react';

/*
 * Registers a history listener on mount which
 * scrolls to the top of the page on route change
 */
export const useScrollTop = () => {
    const history = useHistory();
    useEffect(() => {
        const unlisten = history.listen(() => {
            window.scrollTo(0, 0);
        });
        return unlisten;
    }, [history]);
};

ชัดเจนมากขอบคุณ
นาธาน

ไม่มีค่าอะไรที่ scrollTo () ใช้ไม่ได้ใน IE11 window.scrollTop = 0เป็นทางเลือกที่ดี
นาธาน

3

วิธีแก้ปัญหาของฉัน: ส่วนประกอบที่ฉันใช้ในส่วนประกอบหน้าจอของฉัน (ที่ฉันต้องการเลื่อนขึ้นไปด้านบน)

import { useLayoutEffect } from 'react';

const ScrollToTop = () => {
    useLayoutEffect(() => {
        window.scrollTo(0, 0);
    }, []);

    return null;
};

export default ScrollToTop;

สิ่งนี้จะรักษาตำแหน่งการเลื่อนเมื่อย้อนกลับ การใช้ useEffect () เป็นปัญหาสำหรับฉันเมื่อย้อนกลับเอกสารจะเลื่อนไปด้านบนและยังมีผลกะพริบเมื่อเปลี่ยนเส้นทางในเอกสารที่เลื่อนไปแล้ว


2

withScrollToTopผมเขียนชิ้นส่วนขั้นสูงที่เรียกว่า HOC นี้มีสองแฟล็ก:

  • onComponentWillMount- เลื่อนไปด้านบนหรือไม่เมื่อนำทาง ( componentWillMount)
  • onComponentDidUpdate- เลื่อนไปด้านบนหรือไม่เมื่ออัปเดต ( componentDidUpdate) ธงนี้เป็นสิ่งจำเป็นในกรณีที่มีองค์ประกอบไม่ได้เดินเท้า แต่เหตุการณ์นำทางเกิดขึ้นตัวอย่างเช่นจากการ/users/1/users/2

// @flow
import type { Location } from 'react-router-dom';
import type { ComponentType } from 'react';

import React, { Component } from 'react';
import { withRouter } from 'react-router-dom';

type Props = {
  location: Location,
};

type Options = {
  onComponentWillMount?: boolean,
  onComponentDidUpdate?: boolean,
};

const defaultOptions: Options = {
  onComponentWillMount: true,
  onComponentDidUpdate: true,
};

function scrollToTop() {
  window.scrollTo(0, 0);
}

const withScrollToTop = (WrappedComponent: ComponentType, options: Options = defaultOptions) => {
  return class withScrollToTopComponent extends Component<Props> {
    props: Props;

    componentWillMount() {
      if (options.onComponentWillMount) {
        scrollToTop();
      }
    }

    componentDidUpdate(prevProps: Props) {
      if (options.onComponentDidUpdate &&
        this.props.location.pathname !== prevProps.location.pathname) {
        scrollToTop();
      }
    }

    render() {
      return <WrappedComponent {...this.props} />;
    }
  };
};

export default (WrappedComponent: ComponentType, options?: Options) => {
  return withRouter(withScrollToTop(WrappedComponent, options));
};

วิธีใช้:

import withScrollToTop from './withScrollToTop';

function MyComponent() { ... }

export default withScrollToTop(MyComponent);

1

นี่เป็นอีกวิธีหนึ่ง

สำหรับreact-router v4คุณสามารถผูกผู้ฟังเพื่อเปลี่ยนแปลงเหตุการณ์ในประวัติศาสตร์ได้ในลักษณะต่อไปนี้:

let firstMount = true;
const App = (props) => {
    if (typeof window != 'undefined') { //incase you have server-side rendering too             
        firstMount && props.history.listen((location, action) => {
            setImmediate(() => window.scrollTo(0, 0)); // ive explained why i used setImmediate below
        });
        firstMount = false;
    }

    return (
        <div>
            <MyHeader/>            
            <Switch>                            
                <Route path='/' exact={true} component={IndexPage} />
                <Route path='/other' component={OtherPage} />
                // ...
             </Switch>                        
            <MyFooter/>
        </div>
    );
}

//mounting app:
render((<BrowserRouter><Route component={App} /></BrowserRouter>), document.getElementById('root'));

ระดับการเลื่อนจะถูกตั้งค่าเป็น 0 setImmediate()หากไม่มีการเปลี่ยนเส้นทางด้วยการคลิกที่ลิงค์ แต่หากผู้ใช้กดปุ่มย้อนกลับบนเบราว์เซอร์ก็จะไม่ทำงานเนื่องจากเบราว์เซอร์รีเซ็ตระดับการเลื่อนด้วยตนเองไปที่ระดับก่อนหน้าเมื่อกดปุ่มย้อนกลับ ดังนั้นการใช้setImmediate()เราทำให้ฟังก์ชันของเราถูกเรียกใช้งานหลังจากที่เบราว์เซอร์เสร็จสิ้นการรีเซ็ตระดับการเลื่อนจึงทำให้เราได้เอฟเฟกต์ที่ต้องการ


1

ด้วย React router dom v4 ที่คุณสามารถใช้ได้

สร้างองค์ประกอบ scrollToTopComponent เช่นเดียวกับด้านล่าง

class ScrollToTop extends Component {
    componentDidUpdate(prevProps) {
      if (this.props.location !== prevProps.location) {
        window.scrollTo(0, 0)
      }
    }

    render() {
      return this.props.children
    }
}

export default withRouter(ScrollToTop)

หรือหากคุณกำลังใช้แท็บให้ใช้สิ่งที่ต้องการด้านล่าง

class ScrollToTopOnMount extends Component {
    componentDidMount() {
      window.scrollTo(0, 0)
    }

    render() {
      return null
    }
}

class LongContent extends Component {
    render() {
      <div>
         <ScrollToTopOnMount/>
         <h1>Here is my long content page</h1>
      </div>
    }
}

// somewhere else
<Route path="/long-content" component={LongContent}/>

หวังว่าสิ่งนี้จะช่วยได้มากขึ้นเกี่ยวกับการคืนค่าการเลื่อนดูเอกสาร hare react router dom scroll


0

ฉันพบว่าReactDOM.findDomNode(this).scrollIntoView()ใช้งานได้ componentDidMount()ฉันวางมันไว้ภายใน


1
เป็นสิ่งภายในที่ไม่มีเอกสารซึ่งอาจเปลี่ยนแปลงโดยไม่สังเกตเห็นและรหัสของคุณจะหยุดทำงาน
Lukas Liesis

0

สำหรับแอปขนาดเล็กที่มี 1-4 เส้นทางคุณสามารถลองแฮ็กโดยเปลี่ยนเส้นทางไปยังองค์ประกอบ DOM ด้านบนโดยใช้ #id แทนเส้นทาง จากนั้นไม่จำเป็นต้องตัด Routes ใน ScrollToTop หรือใช้วิธี Lifecycle


0

ในของคุณrouter.jsเพียงแค่เพิ่มฟังก์ชันนี้ในrouterวัตถุ นี้จะทำงาน

scrollBehavior() {
        document.getElementById('app').scrollIntoView();
    },

แบบนี้,

**Routes.js**

import vue from 'blah!'
import Router from 'blah!'

let router = new Router({
    mode: 'history',
    base: process.env.BASE_URL,
    scrollBehavior() {
        document.getElementById('app').scrollIntoView();
    },
    routes: [
            { url: "Solar System" },
            { url: "Milky Way" },
            { url: "Galaxy" },
    ]
});

0

นี่เป็นแนวทางของฉันตามสิ่งที่คนอื่น ๆ เคยทำในโพสต์ก่อนหน้านี้ สงสัยว่านี่จะเป็นแนวทางที่ดีในปี 2020 โดยใช้ตำแหน่งที่ตั้งเป็นที่พึ่งพาเพื่อป้องกันการแสดงซ้ำหรือไม่?

import React, { useEffect } from 'react';
import { useLocation } from 'react-router-dom';

function ScrollToTop( { children } ) {
    let location = useLocation();

    useEffect( () => {
        window.scrollTo(0, 0);
    }, [ location ] );

    return children
}

-2
render() {
    window.scrollTo(0, 0)
    ...
}

อาจเป็นวิธีแก้ปัญหาง่ายๆในกรณีที่อุปกรณ์ประกอบฉากไม่ได้เปลี่ยนและไม่ทำงาน componentDidUpdate ()


-12

นี่คือแฮ็ก (แต่ใช้งานได้): ฉันเพิ่งเพิ่ม

window.scrollTo (0,0);

การแสดงผล ();


2
ดังนั้นมันจะเลื่อนขึ้นทุกครั้งที่มีการเปลี่ยนแปลงสถานะและการแสดงผลใหม่เกิดขึ้นไม่ใช่เมื่อการนำทางเปลี่ยนไป ตรวจสอบคำตอบของฉัน
Lukas Liesis
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.