2015-12-24 53 views
0

我正在構建一個組合網站與React,我想模仿一個典型的網站的行爲。當我點擊一個特定的項目時,我被路由到一個新的URL,但是,滾動條的位置仍然與'上一頁'頁面相同,除了第一次點擊一個項目(如果我單擊後退按鈕並單擊一個新項目,滾動條位於相同位置)。我希望窗口每次點擊一個項目時滾動到頂部。反應:window.scrollTo(0,0)在組件渲染每次

class Project extends React.Component { 
    render() { 
     let project = this.props.project; 
     let linkTo = "/work/" + project.id; 

     return (
      <figure> 
       <img src={project.thumbnail} /> 
       <figcaption> 
        <h3>{project.title}</h3> 
        <p>{project.type}</p> 
       </figcaption> 
       <Link to={linkTo} /> 
      </figure> 
     ) 
    } 
} 

export default Project; 

點擊一個項目組件將路由到「work /:id」渲染ProjectDetail組件。

class ProjectDetail extends React.Component { 
    // componentDidMount() { 
    // window.scrollTo(0,0); 
    // } 

    // componentWillUpdate() { 
    // window.scrollTo(0,0); 
    // } 

    render() { 
     // window.scrollTo(0,0); 
     let project = PROJECTS.find((item) => item.id == this.props.params.id); 
     return (
      <DetailMain project={project} /> 
     ) 
    } 
} 

export default ProjectDetail; 

因此,每次渲染項目組件時,我都希望窗口滾動到頂部。你可以看到我一直試圖讓滾動工作。

回答

1

你可以用react-routerhistory來做到這一點。

陣營路由器

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

實測值here

歷史

使用history.listen要在location更改時通知。

import { createHistory } from 'history'; 

let history = createHistory(); 

// Listen for changes to the current location. The 
// listener is called once immediately. 
let unlisten = history.listen(function(location) { 
    console.log(location.pathname); 
    // scroll logic here 
}) 

// When you're finished, stop the listener. 
unlisten(); 

更多關於here

+0

感謝您的回覆。第一個選項部分起作用。如果我點擊一個項目,點擊'返回',但不要滾動,點擊相同或新的項目,scrollTo(0,0)不起作用。但是,如果我點擊某個項目,請點擊「返回」並在該頁面上移動,然後點擊相同或新的項目,一切正常。對此有何想法?這是因爲onUpdate沒有被調用? – user2909019

+0

此外,第二個選項似乎工作。我添加了一個答案。 – user2909019

0

我可以使用這裏提供的代碼來解決我的問題:https://github.com/rackt/react-router/issues/2144

var history = createBrowserHistory(); 

history.listen(location => { 
    // Use setTimeout to make sure this runs after React Router's own listener 
    setTimeout(() => { 
    // Keep default behavior of restoring scroll position when user: 
    // - clicked back button 
    // - clicked on a link that programmatically calls `history.goBack()` 
    // - manually changed the URL in the address bar (here we might want 
    // to scroll to top, but we can't differentiate it from the others) 
    if (location.action === 'POP') { 
     return; 
    } 
    // In all other cases, scroll to top 
    window.scrollTo(0, 0); 
    }); 
}); 

var routes = (
    <Router history={history}> 
    // ... 
    </Router> 
); 

這似乎直到一些被集成在反應路由器現在的工作。