简体   繁体   English

React-Router链接,如何触发来自另一个组件的链接上的点击事件

[英]React-Router Link, how to trigger a click event on a Link from another component

I'm trying to set up a series of React-Router to have navigation within a certain component. 我正在尝试建立一系列React-Router以在某个组件内进行导航。 I have it set up so the link tags work correctly but I'm trying to style them to look like this: 我已经设置好了,所以链接标记可以正常工作,但是我正在尝试将其样式设置为如下所示:

在此处输入图片说明

The styling is set up like this: 样式设置如下:

  <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>

And the current series of Links looks like this (with no styling): 当前的链接系列看起来像这样(没有样式):

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

The HTML (top) is written in HTML, not JSX, but that's not the issue. HTML(顶部)是用HTML而不是JSX编写的,但这不是问题。 I am trying to combine the Link Components into the HTML above so that the options will trigger the functionality of the link tags. 我试图将链接组件合并到上面的HTML中,以便这些选项将触发链接标签的功能。

In the React documentation I found this: 在React文档中,我发现了这一点:

For communication between two components that don't have a parent-child relationship, you can set up your own global event system. 要在没有父子关系的两个组件之间进行通信,可以设置自己的全局事件系统。 Subscribe to events in componentDidMount(), unsubscribe in componentWillUnmount(), and call setState() when you receive an event. 订阅componentDidMount()中的事件,取消订阅componentWillUnmount()中的事件,并在收到事件时调用setState()。 Flux pattern is one of the possible ways to arrange this. 助焊剂模式是解决此问题的一种可能方法。

So this gave me the idea of putting the Link tags inside of their respective labels, giving them a style of {{display: 'none'}}, and having the clicks on the radio buttons trigger a click on the respective Link tag. 因此,这给了我一个将Link标签放在其各自标签内的想法,使它们具有{{display:'none'}}的样式,并且单击单选按钮会触发对相应Link标签的点击。 That would ensure all the same functionality happens that we'd expect from the Link tag (pushing to browser history etc). 这将确保所有相同的功能都发生在Link标记中我们期望的(推送到浏览器历史记录等)。

However, the following is not working: 但是,以下内容不起作用:

<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>

In the previous example you can see I created an onClick event handler that selects the id of the Link tag and triggers a click. 在前面的示例中,您可以看到我创建了一个onClick事件处理程序,该处理程序选择Link标记的ID并触发点击。

I was able to solve my problem so I am posting what worked for me. 我能够解决我的问题,所以我发布了对我有用的东西。 Please answer or comment if there's changes or a better solution. 如果有更改或更好的解决方案,请回答或评论。

I wasn't able to trigger a click event on a Link, but I was able to simulate the aspects that I needed. 我无法在链接上触发点击事件,但可以模拟所需的方面。

For this to work I needed the following: 为此,我需要以下内容:

  1. on a click event push to browserHistory to update the route 在点击事件上推送到browserHistory以更新路线
  2. link the 'active' css class to the current view/URL (I accomplished this through component state) 将“活动的” css类链接到当前视图/ URL(我通过组件状态完成了此操作)
  3. update the state whenever the url is changed (modified state on window popstate event, and also update the currentView state on component will mount) 每当更改url时更新状态(在窗口popstate事件上修改状态,并在组件上安装currentView状态也将挂载)

This results in the ability for the correct tab to be highlighted when a tab is clicked, when the url is manually changed to a certain route, and when the browsers back / forward buttons are used. 这样可以在单击选项卡,将URL手动更改为特定路径以及使用浏览器的后退/前进按钮时突出显示正确的选项卡。

This is all the code in my navmenu file that creates a pretty cool navigation component and works with react-router and browserHistory. 这就是我的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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM