4

I am writing a table application using RiotJS and I keep running into the same problem with the onclick event. Almost every time I try to use the

<tag onclick={somefunction}>

I get very erratic behaviour. Sometimes it will call the function a whole bunch of times as the page loads or updates, and then not respond to clicks at all, other times it will triggered several times at launch. I can't seem to figure out a pattern behind the problem, although I have noticed that it tends to be a problem with in line function calls e.g.

<tag onclick={console.log("foo")}>

and less often with reference passing <tag onclick={function}> although it happens with both. Has anybody experienced anything like this? Please comment if you need more context.

stmfunk
  • 663
  • 5
  • 20
  • 2
    try `onclick={somefunc.bind('blah')}` https://github.com/riot/riot/issues/1001 – Daniel Lizik Aug 03 '16 at 14:03
  • 1
    You can't use `{console.log("foo")}` since that execute/evaluates as it parses, then not at all `onclick`. As @Daniel_L said, if you want to pass args, you can use `.bind` or set `data-` or similar, as mentioned in http://github.com/riot/riot/issues/1001 – user1278519 Aug 04 '16 at 07:24
  • If you don't like: `` then use a closure: `somefunction(){ /private vars*/ returns function(){ /*access to private vars */ /*preform your click logic*/ }}` so your template looks like `` – Simon Apr 29 '17 at 09:17
  • doing `somefunc.bind('blah')` will work, but it has an odd side-effect... that being it creates a new function every time the tag gets updated because `.bind()` creates a new function and returns it when it's executed. This _probably_ won't break your app, but if this tag hangs around a long time, it will add a lot of function creation / destruction to your app and can slow it down over time. – JayKuri Aug 29 '17 at 17:01

1 Answers1

3

In Riot the {} expressions are evaluated at mount / update time.

This means that if what is inside the {} is a function call, it will get executed when the mounted tag gets updated, every time the section it is in gets evaluated.

This is different from vanilla javascript where onclick won't even be parsed until the thing is clicked.

This can lead to some confusion, because Riot doesn't always parse {} expressions the way you think. This is especially troublesome with compound expressions (those with boolean logic || and && etc.)

In this case, onclick in Riot is looking for an expression / function... and it will try to evaluate it in terms of the tag itself... in other words, this:

<button onclick={foobar}>Click me!</button>

Riot will try to execute this.foobar() when clicked.

Generally, I try to take advantage of this by setting my methods on this in the <script> portion of the tag. This leaves very little room for misinterpretation of my {} expressions, and moves the bits of logic out of the HTML portion of the tag and into where I expect the behavior to be, in the script portion.

JayKuri
  • 839
  • 5
  • 10