How is it better to add multiple event listeners in the same ponent in a more reusable way?
ponentDidMount: function() {
window.addEventListener('resize', this.handleVisible);
window.addEventListener('scroll', this.handleVisible);
...
},
ponentWillUnmount: function() {
window.removeEventListener('resize', this.handleVisible);
window.removeEventListener('scroll', this.handleVisible);
...
},
How is it better to add multiple event listeners in the same ponent in a more reusable way?
ponentDidMount: function() {
window.addEventListener('resize', this.handleVisible);
window.addEventListener('scroll', this.handleVisible);
...
},
ponentWillUnmount: function() {
window.removeEventListener('resize', this.handleVisible);
window.removeEventListener('scroll', this.handleVisible);
...
},
Share
Improve this question
asked Apr 6, 2020 at 10:30
user12009061user12009061
2
- You could create a custom hook for that. – Barry Michael Doyle Commented Apr 6, 2020 at 10:33
-
window.addEventListener('resize scroll', this.handleVisible);
– Nicolae Maties Commented Apr 6, 2020 at 10:34
2 Answers
Reset to default 3You could create a custom hook like this:
import { useEffect } from 'react'
export const useResizeScroll = callback => {
useEffect(() => {
window.addEventListener('resize scroll', callback);
return () => window.removeEventListener('resize scroll', callback);
}, [callback]);
};
Then implement it in your ponent like this:
const MyComponent = () => {
useResizeScroll(handleVisible)
function handleVisible() { ... }
return (...)
}
Note:
This will required you to move over to a hooks implementation of your ponent.
So if you were using this.state = { ... }
, you'll need to go learn how to make use of React's useState
hook: React useState Hook
UPDATE:
If you want the hook to be more flexible, like selecting what event listeners you want the ponent to hook onto, then you could do this:
export const useResizeScroll = (eventListener, callback) => {
useEffect(() => {
window.addEventListener(eventListener, callback);
return () => window.removeEventListener(eventListener, callback);
}, [callback]);
};
And then implement it like this:
useResizeScroll('resize scroll', handleVisible)
More Advanced Use Case:
You could also improve your custom hook by making use of React Context. Here's an example of implementing a hook that keeps track of your window width.
import React, { createContext, useContent, useEffect, useState } from 'react'
const ViewportContext = createContext({ width: window.innerWidth })
export const ViewportProvider = ({ children }) => {
const [width, setWidth] = useState(window.innerWidth)
function handleResize() {
setWidth(window.innerWidth)
}
useEffect(() => {
window.addEventListener('resize', handleResize)
return () => window.removeEventListener('resize', handleResize)
}, [])
return (
<ViewportContext.Provider value={{ width }}>
{children}
</ViewportContext.Provider>
)
}
export const useViewport = () => {
const { width } = useContext(ViewportContext)
return { width }
}
Then you can use it in any ponent like this:
const { width } = useViewport()
This should provide you with enough information to build a custom hook to match your use case.
This :
window.addEventListener('resize scroll', callback);
didn't work for me.
I had to to do :
window.addEventListener('resize', callback);
window.addEventListener('scroll', callback);
But this worked :
window.removeEventListener('resize scroll', handleResize)