Skip to content

Commit 10500be

Browse files
committed
Posted useEventListener
1 parent 8691abe commit 10500be

File tree

1 file changed

+14
-0
lines changed

1 file changed

+14
-0
lines changed

src/pages/useEventListener.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
---
2+
templateKey: post
3+
title: useEventListener
4+
date: "2019-03-05"
5+
gist: https://gist.github.com/gragland/ae701852ae6159c712d860a946cd7ca0
6+
sandbox: https://codesandbox.io/s/z64on3ypm
7+
links:
8+
- url: https://github.com/donavon/use-event-listener
9+
name: donavon/use-event-listener
10+
description: Original source for this hook available as a library
11+
code: "import { useRef, useEffect } from 'react';\r\n\r\n\/\/ Usage\r\nfunction App(){\r\n \/\/ State for storing mouse coordinates\r\n const [coords, setCoords] = useState([0, 0]);\r\n \r\n \/\/ Add event listener using our hook\r\n useEventListener('mousemove', ({ clientX, clientY }) => {\r\n \/\/ Update coordinates\r\n setCoords([clientX, clientY]);\r\n });\r\n \r\n return (\r\n <h1>\r\n The mouse position is ({coords.x}, {coords.y})\r\n <\/h1>\r\n );\r\n}\r\n\r\n\/\/ Hook\r\nfunction useEventListener(eventName, handler, element = global){\r\n \/\/ Create a ref that stores handler\r\n const savedHandler = useRef();\r\n \r\n \/\/ Update ref.current value if handler changes.\r\n \/\/ This allows our effect below to always get latest handler ...\r\n \/\/ ... without us needing to pass it in effect deps array ...\r\n \/\/ ... and potentially cause effect to re-run every render.\r\n useEffect(() => {\r\n savedHandler.current = handler;\r\n }, [handler]);\r\n\r\n useEffect(\r\n () => {\r\n \/\/ Make sure element supports addEventListener\r\n const isSupported = element && element.addEventListener;\r\n if (!isSupported) return;\r\n \r\n \/\/ Create event listener that calls handler function stored in ref\r\n const eventListener = event => savedHandler.current(event);\r\n \r\n \/\/ Add event listener\r\n element.addEventListener(eventName, eventListener);\r\n \r\n \/\/ Remove event listener on cleanup\r\n return () => {\r\n element.removeEventListener(eventName, eventListener);\r\n };\r\n },\r\n [eventName, element] \/\/ Re-run if eventName or element changes\r\n );\r\n};"
12+
---
13+
14+
If you find yourself adding a lot of event listeners using `useEffect` you might consider moving that logic to a custom hook. In the recipe below we create a `useEventListener` hook that handles checking if `addEventListener` is supported, adding the event listener, and removal on cleanup. See it in action in the [CodeSandbox demo](https://codesandbox.io/s/z64on3ypm).

0 commit comments

Comments
 (0)