React-Router Link, как вызвать событие click по ссылке из другого компонента

Я пытаюсь настроить серию React-Router для навигации в определенном компоненте. У меня он настроен так, что теги ссылок работают правильно, но я пытаюсь их стилизовать так:

enter image description here

стиль настроен следующим образом:

  <div className="btn-group" data-toggle="buttons">
      <label className="btn btn-primary-outline active">
        <input type="radio" name="options" id="option1" autocomplete="off" checked />Payments
      </label>
      <label className="btn btn-primary-outline">
        <input type="radio" name="options" id="option2" autocomplete="off" /> Bills
      </label>
      <label className="btn btn-primary-outline">
        <input type="radio" name="options" id="option3" autocomplete="off" /> Charge
      </label>
    </div>

и текущая серия ссылок выглядит так (без стиля):

<ul>
  <Link to='/options/option1'>option1</Link>
  <Link to='/options/option2'>option2</Link>
  <Link to='/options/option3'>option3</Link>
</ul>

HTML (сверху) написан в HTML, а не JSX, но это не проблема. Я пытаюсь чтобы объединить компоненты ссылок в HTML выше, чтобы параметры запускали функциональность тегов ссылок.

в документации React я нашел это:

для связи между двумя компонентами, которые не имеют отношения "родитель-потомок", можно настроить собственную глобальную систему событий. Подпишитесь на события в componentDidMount(), отпишитесь в componentWillUnmount() и вызовите setState () при получении события. Картина потока одно из возможные способы это устроить.

таким образом, это дало мне идею поместить теги ссылок внутри их соответствующих меток, давая им стиль {{display: 'none'}}, и щелчки по переключателям вызывают щелчок по соответствующему тегу ссылки. Это обеспечит все те же функциональные возможности, которые мы ожидаем от тега ссылки (нажатие на историю браузера и т. д.).

однако следующее не работает:

<label className="btn btn-primary-outline active" onClick={() => document.getElementById('linkToOption1').click() }>
    <Link to='/options/option1' id="linkToOption1" style={{display: 'none'}}>Option1</Link>
        <input type="radio" name="options" id="option1" autoComplete="off" defaultChecked />Option1
    </label>

В предыдущем пример вы можете видеть, что я создал обработчик событий onClick, который выбирает идентификатор тега ссылки и запускает щелчок.

1 ответов


я смог решить свою проблему, поэтому я публикую то, что сработало для меня. Пожалуйста, ответьте или прокомментируйте, если есть изменения или лучшее решение.

Я не смог вызвать событие click по ссылке, но я смог имитировать аспекты, которые мне нужны.

для этого мне нужно было следующее:

  1. на событие нажмите кнопку browserHistory, чтобы обновить маршрут
  2. связать "активный" класс css с текущим представлением / URL (я выполнил это через состояние компонента)
  3. обновите состояние при изменении url-адреса (измененное состояние в событии window popstate, а также обновите состояние currentView в компоненте)

это приводит к возможности выделения правильной вкладки при нажатии на вкладку, когда url-адрес вручную изменяется на определенный маршрут и когда используются кнопки Назад / Вперед браузеров.

Это весь код в моем файле navmenu, который создает довольно классный навигационный компонент и работает с react-router и browserHistory.

import React, { Component, PropTypes } from 'react'
import { Link, browserHistory } from 'react-router'

class Navmenu extends Component {
  constructor(props) {
    super(props)
    this.state = { currentView: '' }
    this.getClasses.bind(this)
  }

  // in case of url being manually set, figure out correct tab to highlight
  // add event listener to update the state whenever the back/forward buttons are used.
  componentWillMount() {
    this.changeLocation()
    window.addEventListener('popstate', this.changeLocation.bind(this))
  }

  componentWillUnmount() {
    window.removeEventListener('popstate', this.changeLocation.bind(this))
  }

  // update state based on the URL
  changeLocation() {
    const path = window.location.pathname.split('/')
    const currentView = path[path.length - 1]
    this.setState({ currentView })
  }

  // update state and update react-router route
  navigateToRoute(route) {
    this.setState({ currentView: route })
    browserHistory.push(`/options/${route}`)
  }

  // give correct tab the 'active' bootstrap class
  getClasses(link) {
    let classes = 'btn btn-primary-outline flex-button'
    if (this.state.currentView === link) {
      classes += ' active'
    }
    return classes
  }

  render() {
    return (
      <div className="btn-group flex-navbar" data-toggle="buttons">
        <label className={this.getClasses('option1')} onClick={() => this.navigateToRoute('option1')}>
          <input type="radio" name="options" id="option1" autoComplete="off" defaultChecked />option1
        </label>
        <label className={this.getClasses('option2')} onClick={() => this.navigateToRoute('option2')}>
          <input type="radio" name="options" id="option2" autoComplete="off" /> option2
        </label>
        <label className={this.getClasses('option3')} onClick={() => this.navigateToRoute('option3')}>
          <input type="radio" name="options" id="option2" autoComplete="off" /> option3
        </label>
      </div>
    )
  }
}

export default Navmenu