-
Notifications
You must be signed in to change notification settings - Fork 411
Beware Event Handlers Returning False
There is a trap when writing DOM event handlers that might return false. (We are talking here about DOM event handlers, not re-frame event handlers.)
This code looks innocent enough:
:on-mouse-out #(reset! mouse-over-atom false)
But notice that it inadvertently returns false, and returning false means something: React will stop event propagation by invoking both stopPropagation() and preventDefault() on the event. This is almost certainly not what you want.
Furthermore, React v0.12 and 0.13 issue a deprecation warning, noting that this behavior will be ignored in a future release.
Note: the return value is tested explicitly for false, not falsy values. So 'nil' is a safe return value.
Relevant code in React v0.11, v0.12, v0.13.
Below, handler-fn
is a macro which will stop you from inadvertently
returning false in a handler.
(defmacro handler-fn
([& body]
`(fn [~'event] ~@body nil))) ; always return nil
Usage Examples:
:on-mouse-out (handler-fn (reset! mouse-over-atom false))
:on-mouse-out (handler-fn
(reset! mouse-over-atom false) ; note: no need for a 'do'
; now do something else
(.preventDefault event)) ; explicitly prevent event propagation
In summary, there are two issues:
- If you accidentally return false in v0.11, v0.12, and v0.13, you'll get an unexpected outcome (preventDefault and stopPropagation). This can be a baffling bug, and it's an easy trap to fall into. Use the macro above to always return nil.
- if you deliberately return false to cause event cancellation and
stopPropagation()
, be aware that this won't work in an (unspecified) future version. Use the macro above with an explicit call to(.preventDefault event)
to get the desired behavior.