129

I am using the Link component from the reactjs router and I cannot get the onClickevent working. This is the code:

<Link to={this.props.myroute} onClick='hello()'>Here</Link>

Is this the way to do it or another way?

bier hier
  • 20,970
  • 42
  • 97
  • 166

7 Answers7

164

You are passing hello() as a string, also hello() means execute hello immediately.

try

onClick={hello}
CodinCat
  • 15,530
  • 5
  • 49
  • 60
59

You should use this:

<Link to={this.props.myroute} onClick={hello}>Here</Link>

Or (if method hello lays at this class):

<Link to={this.props.myroute} onClick={this.hello}>Here</Link>

Update: For ES6 and latest if you want to bind some param with click method, you can use this:

    const someValue = 'some';  
....  
    <Link to={this.props.myroute} onClick={() => hello(someValue)}>Here</Link>
Vitalii Andrusishyn
  • 3,984
  • 1
  • 25
  • 31
  • 5
    Or better `this.hello.bind(this)` – webNeat Aug 14 '17 at 12:22
  • 4
    ^ You should actually always bind actions in the constructor as binding the way you have can lead to performance issues. – Nunchucks Apr 26 '18 at 00:47
  • 5
    Link "to" is required, but often times I just need onClick(), currently, I have to do something like `Delete`. I wish "to" is optional here. – newman Aug 09 '18 at 21:35
  • 7
    @newman Why would you use `Link` without `to`? If you don't need it, then just some other component such as a ` – Guilherme Oderdenge Oct 29 '18 at 20:15
  • I'm not entirely sold on React-Router nor Link either. Sometimes it is there because of what the last developer did. I'd prefer handling the reactivity up and down thru props for control over the workflow. – justdan23 Oct 20 '21 at 19:07
  • as @GuilhermeOderdenge mentioned it is better and more practical to use the **button tag**. **Use styling to make it display as link**. ie if you are using bootstrap you could go with `button type="button" class="btn btn-link" onClick={your_click_fn}>Link` – Nwawel A Iroume Sep 15 '22 at 10:52
36

I don't believe this is a good pattern to use in general. Link will run your onClick event and then navigate to the route, so there will be a slight delay navigating to the new route. A better strategy is to navigate to the new route with the 'to' prop as you have done, and in the new component's componentDidMount() function you can fire your hello function or any other function. It will give you the same result, but with a much smoother transition between routes.

For context, I noticed this while updating my redux store with an onClick event on Link like you have here, and it caused a ~.3 second blank-white-screen delay before mounting the new route's component. There was no api call involved, so I was surprised the delay was so big. However, if you're just console logging 'hello' the delay might not be noticeable.

Nunchucks
  • 1,182
  • 10
  • 14
  • I have a callback url in my current component which I am saving in cookie in `onClick` before transitioning to new route. I wont get that callback url in next component so I need to do that before transition itself. Do you have any alternative to that? PS: The callback url should be accessible even after refresh so can save it in store. – Parth Mistry Oct 25 '18 at 11:04
  • 2
    If you're using react-navigation: I would say don't use Link, just use TouchableOpacity or TouchableWithoutFeedback, then in your onPress function you can navigate and pass your url as a nav param ```onPress={() => { this.props.navigation.navigate('NameOfNextScreen', { callbackUrl: 'http://.callbackUrl.com', });``` If you aren't using react-navigation I would just use Link's onClick and don't worry about the slight performance issue. It probably won't be noticeable. – Nunchucks Oct 25 '18 at 18:17
  • 1
    Good advice! Thanks! – aspiringsoftwaredev Aug 29 '20 at 03:43
  • I think this could be perfectly fine, simpy handle the click passing the event and handle some logic to see what you want to do and if you decide not to use the route change call ` event.preventDefault()`. I do get your point, but I had a use case where I needed to intercept the click and warn a user they where moving away from a route and if they were sure about that. – sidneydobber Feb 17 '22 at 11:41
  • So would you say that you would use onClick on a Link if you need to do something else like erase a session or local storage token when you click on logout? – Imriven Apr 05 '22 at 17:46
  • @Imriven I was just pointing out that there is a slight performance hit to consider if you use this pattern (slight delay navigating to new route). If that's not an issue for your use-case, go for it! Personally I would just have a logout button rather than using a and navigate programmatically in my onPress function using history. If you've set up authenticated routes, when you clear your token your app should redirect to the login screen automatically. – Nunchucks Apr 11 '22 at 21:43
4
 const onLinkClick = (e) => {
    e.preventDefault();
    ---do your stuff---
    history.push('/your-route');
};

<a href='/your-route' onClick={onLinkClick}> Navigate </a>
                   or
<Link to='/your-route' onClick={onLinkClick}> Navigate </Link>
Vivek
  • 176
  • 1
  • 8
  • @AdamHey You mean event delegation. Apparently there's no noticeable performance benefits due to optimizations in React. https://dev.to/thawsitt/should-i-use-event-delegation-in-react-nl0 – manafire Aug 22 '21 at 15:07
  • Thanks for the link @manafire. I wasn't really thinking in performance terms, but more from a manageability perspective. if you can write a delegate that targets all the desired elements then you don't need to add `onClick` on every element – Adam Hey Aug 23 '21 at 00:47
  • Where's the history coming from? – verunar Sep 24 '21 at 11:07
  • @AdamHey Solution was more around understanding the concept. Also, there are pros and cons to each usage. handlers mostly give us the advantage to write custom logic – Vivek May 30 '22 at 06:29
  • @verunar history would come from router hook or previously via withRouter HoC ```https://v5.reactrouter.com/web/api/Hooks``` – Vivek May 30 '22 at 06:31
1

Be careful with the function, in this case hello, you may avoid writing event.preventDefault(), otherwise the Link to won't work.

Pradc
  • 11
  • 1
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Oct 10 '22 at 13:39
0
  1. Link to use in react onClick event
    <a href="#" onClick={this.setActiveTab}>
      ...View Full List
    </a>
    
    setActiveTab = (e) => {
      e.preventDefault();
      console.log(e.target);
    }
    
Saeed Zhiany
  • 2,051
  • 9
  • 30
  • 41
Sandeep Jain
  • 1,019
  • 9
  • 13
0

in ReactJs we have to use {} to use our Handlers use onClick={ ()=> hello() } instead of onClick='hello()'

Helper document => https://reactjs.org/docs/handling-events.html