I'm using Material UI for a fairly simple website but I'm having trouble with ScrollToTop. I've followed the documentation but can't seem to find the issue with my code. The desired functionality is every time a link is clicked, the page loads at the top. Instead, when clicked, the page changes but is rendered in the same position as the previous. See below - I've simplified the code so you aren't blasted with a wall of text.
Documentation referenced: https://reacttraining.com/react-router/web/guides/scroll-restoration
Root Component
const homePage = () => (<Home />);
const helpPage = () => (<Help />);
const termsPage = () => (<Markdown>{terms}</Markdown>);
const privacyPage = () => (<Markdown>{privacy}</Markdown>);
class Header extends React.Component {
componentDidUpdate(prevProps) {
if (this.props.location !== prevProps.location) {
window.scrollTo(0, 0);
}
}
render() {
return (
<MuiThemeProvider theme={darkTheme}>
<div className={classes.root}>
<AppBar position="absolute" className={classes.appBar}>
<Toolbar>
<Link className={classes.link} to="/"><Typography>Home</Typography></Link>
<Link className={classes.link} to="/help"><Typography>Help</Typography></Link>
<IconButton onClick={this.props.logOut} className={classes.headerIcon}>
<AccountCircleIcon />
</IconButton>
</Toolbar>
</AppBar>
<main className={classes.content}>
<div className={classes.toolbar} />
<Route exact path="/" component={homePage} />
<Route path="/help" component={helpPage} />
<Route path="/terms" component={termsPage} />
<Route path="/privacy" component={privacyPage} />
<Footer />
</main>
</div>
</MuiThemeProvider>
);
}
}
答案 0 :(得分:1)
I discovered the root of the issue. The ScrollToTop function was referencing the window
, but the content in question was being rendered in the main
element under the Material UI Header. My solution was to reference the main
element - problem solved. See below.
class Header extends React.Component {
main = null;
componentDidUpdate(prevProps) {
if (this.props.location !== prevProps.location) {
this.main.scrollTo(0, 0);
}
}
render() {
return (
<MuiThemeProvider theme={darkTheme}>
<div className={classes.root}>
<AppBar position="absolute" className={classes.appBar}>
<Toolbar>
<Link className={classes.link} to="/"><Typography>Home</Typography></Link>
<Link className={classes.link} to="/help"><Typography>Help</Typography></Link>
<IconButton onClick={this.props.logOut} className={classes.headerIcon}>
<AccountCircleIcon />
</IconButton>
</Toolbar>
</AppBar>
<main ref={(ref) => { this.main = ref; }} className={classes.content}>
<div className={classes.toolbar} />
<Route exact path="/" component={homePage} />
<Route path="/help" component={helpPage} />
<Route path="/terms" component={termsPage} />
<Route path="/privacy" component={privacyPage} />
<Footer />
</main>
</div>
</MuiThemeProvider>
);
}
}
----Edits---- Using React.createRef() as suggested by Pier
class Header extends React.Component {
constructor(props) {
super(props);
this.main = null;
this.setMainRef = (element) => {
this.main = element;
};
}
componentDidUpdate(prevProps) {
if (this.props.location !== prevProps.location) {
this.main.scrollTo(0, 0);
}
}
render() {
return (
<MuiThemeProvider theme={darkTheme}>
<div className={classes.root}>
<AppBar position="absolute" className={classes.appBar}>
<Toolbar>
<Link className={classes.link} to="/"><Typography>Home</Typography></Link>
<Link className={classes.link} to="/help"><Typography>Help</Typography></Link>
<IconButton onClick={this.props.logOut} className={classes.headerIcon}>
<AccountCircleIcon />
</IconButton>
</Toolbar>
</AppBar>
<main ref={this.setMainRef} className={classes.content}>
<div className={classes.toolbar} />
<Route exact path="/" component={homePage} />
<Route path="/help" component={helpPage} />
<Route path="/terms" component={termsPage} />
<Route path="/privacy" component={privacyPage} />
<Footer />
</main>
</div>
</MuiThemeProvider>
);
}
}