React Router ScrollToTop не работает с пользовательским интерфейсом материала

Я использую Material UI для довольно простого веб-сайта, но у меня проблемы с ScrollToTop. Я следил за документацией, но, похоже, не могу найти проблему с моим кодом. Желаемая функциональность - каждый раз при нажатии на ссылку страница загружается вверху. Вместо этого при нажатии страница изменяется, но отображается в том же положении, что и предыдущая. См. Ниже - я упростил код, чтобы вы не взорвали стену текста.

Ссылка на документацию: https://reacttraining.com/react-router/web/guides/scroll-resturation

Корневой компонент

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>
    );
  }
}
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
0
0
721
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я обнаружил корень проблемы. Функция ScrollToTop ссылалась на window, но рассматриваемый контент отображался в элементе main под заголовком пользовательского интерфейса материала. Мое решение состояло в том, чтобы сослаться на элемент main - проблема решена. См. ниже.

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>
    );
  }
}

---- Редактирует ---- Использование React.createRef (), предложенное Пьером

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>
    );
  }
}

Могу я предложить использовать React.createRef вместо ссылки со стрелкой?

Pier Paolo Ramon 19.09.2018 01:18

Отличное предложение. Я дополню свой ответ этой альтернативой.

Seth Duncan 19.09.2018 15:05

Другие вопросы по теме