Недавно, когда я работал над небольшим приложением React для клиента, меня попросили создать «липкий баннер», который бы появлялся на каждой странице сайта. Этот баннер будет содержать ссылку, которая будет перенаправлять пользователя из любой точки сайта на определенную часть определенной страницы. В приложении, не поддерживающем React, такую ​​ссылку можно легко создать с помощью элемента привязки и атрибута href. Однако в React внутреннюю навигацию нельзя обрабатывать с помощью якорных тегов, поэтому мне пришлось искать другой способ.

После нескольких быстрых поисков в Google, чтобы узнать, существует ли общепринятое решение, я обнаружил, что большинство людей, похоже, довольны использованием дополнительных библиотек, таких как react-scroll, но я хотел найти способ использовать встроенные функции response-router. работать на меня. Вот что я нашел!

Для этого я использовал компонент Link от response-router. Я использовал NavLink для своей панели навигации, чтобы воспользоваться преимуществами ее параметров стиля, но компонент Link имеет дополнительные параметры, которые идеально подходят для этой ситуации. В частности, параметры к: объекту, как описано в разделе Обучение реакции.

Теперь, глядя на эти параметры, вы можете подумать, что я бы просто использовал параметр хеширования, но, насколько я могу судить, параметр хеширования работает только при связывании с частью страницы, которая уже была загружена, а не для связывания к совершенно другому компоненту. Вместо этого ключом к этой работе было использование состояния! Как только я узнал, что есть способ передать состояние через мой компонент Link, я понял, что должен быть способ получить доступ к этому состоянию в новом компоненте. Пример, приведенный на сайте, также послужил отличным ключом к пониманию того, как лучше всего использовать это открытие. Вот моя реализация компонента Link:

<div className='banner' onClick={this.handleScroll} >                  
  <Link className='banner-link' to={{                             
    pathname: '/designs',                    
      state: {                        
        fromBanner: true                    
      }                
    }}                
  >                    
    ULTIMATE &nbsp; WEDDING &nbsp; PACKAGE                 
  </Link>            
</div>

После передачи состояния fromBanner: true все, что мне нужно было сделать, это проверить это состояние в компоненте, с которым я связываюсь, а затем предпринять соответствующие действия оттуда. Однако, даже если я отправляю «состояние», это состояние не будет частью состояния компонента, с которым я связываюсь. Вместо этого это состояние будет находиться в свойствах компонента. Добавление console.log(this.props) в ComponentDidMount показывает эту забавную информацию:

Если я загружаю этот компонент, не нажимая на ссылку, это состояние отображается как «null», но со ссылкой состояние показывает, что я прошел через объект to: выше. И вот так почти все на месте. Отсюда мне нужно было сделать только две вещи:

  1. Запустите проверку в ComponentDidMount, чтобы проверить this.props.location.state, а затем прокрутите до соответствующего места, если оно вернется.
  2. Напишите дополнительную логику в ссылку, чтобы она по-прежнему прокручивалась в это место, если по ссылке щелкнуть из целевого Компонента.

Первая часть требовала добавления ссылки на элемент, который я хотел прокрутить. Я создал ссылку в верхней части компонента, написав targetRef=React.CreateRef(), а затем прикрепив эту ссылку к элементу, к которому я хотел прокрутить: <div ref={ref => {this.targetRef = ref}} > *

Наконец, я привел ссылку в действие, вызвав эту функцию в ComponentDidMount моего целевого компонента:

scrollToTarget = () => {
  setTimeout(() => {
    this.targetRef.scrollIntoView({ behavior: 'smooth' })             
  }, 500);    
}
// setTimeout is optional, but instantly scrolling can be jarring

Для второй части я сделал две вещи. Сначала я передал функцию setTimeout компоненту Banner при его вызове из целевого компонента. Во-вторых, я добавил функцию onClick к родительскому элементу Link, которая проверяет опору, которую я передал на предыдущем шаге. Если опора существует, она запускает функцию для прокрутки до целевой ссылки.

Вот и все! Чуть ниже приведен код, который я использовал для своего компонента Banner, за которым следует код целевого компонента. Спасибо за чтение и удачного кодирования!

React Training

Советы по React Refs

Ссылки и ДОМ