2015-12-24 23 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> 
); 

这似乎直到一些被集成在反应路由器现在的工作。