I need to do a global addEventListener
like thing. I am using react native and need to listen for deep link redirect events. I couldn't figure out the redux-saga way to do this. I need to enable a put
from the callback within the addEventListener.
I currently do the bad hack of importing store
then doing store.dispatch(...)
as seen here:
import store from './flow-control'
Linking.addEventListener('url', ({ url }) => store.dispatch(_redir(url)));
Is there a redux-saga way to do this?
I was hoping to put this into a a saga maybe:
function* reduxSaga() {
const url = yield Linking.addEventListener('url', ({ url }) => ???);
}
Or at the least replace store.dispatch with put like this:
import { put } from 'redux-saga/effects'
Linking.addEventListener('url', ({ url }) => put(_redir(url)));
Whats the right way to do this with redux-saga?
addEventListener('click', () => { console. log('element clicked'); }); The code queries the DOM, grabs a specific element and adds a click event listener to it using addEventListener . addEventListener accepts the event type, a listener callback function and an options or useCapture parameter.
How to invoke multiple functions on a single event listener. We can invoke multiple functions on a single event listener without overwriting each other. To do this we simply call the addEventListener() method more than once with a different function.
The "addEventListener is not a function" error occurs for multiple reasons: calling the method on an object that is not a valid DOM element. placing the JS script tag above the code that declares the DOM elements. misspelling the addEventListener method (it's case sensitive).
If you like to have it within listener, you must do something like: someObj. addEventListener("click", function(){ var newVar = someVar; some_function(someVar); }, false); and use newVar instead.
One possible solution, is to use channels. Here is an example that should work in your case:
import { channel } from 'redux-saga'
import { put, take, race } from 'redux-saga/effects'
const redirectChannel = channel()
export function* startRedirectChannel(id) {
Linking.addEventListener('url', ({ url }) => redirectChannel.put({
type: REDIRECT,
url,
}))
}
export function* watchRedirectChannel() {
while (true) {
const action = yield take(redirectChannel)
yield put(action)
}
}
The idea here is that we will push a REDIRECT action on the channel for each url event that is emitted from Linking.addEventListener.
We also have to start another saga function that is listening to each pushed action in a while loop (watchRedirectChannel). Everytime an action has been taken from the channel, we use the normal yield put to tell redux-saga that this action should be dispatched.
Here an example using the eventChannel
API:
import { eventChannel } from 'redux-saga'
import { put, take } from 'redux-saga/effects'
export function* watchRedirect() {
const redirectChannel = eventChannel(emitter => {
Linking.addEventListener('url', emitter)
// The subscriber must return an unsubscribe function
return () => {
Linking.removeEventListener('url', emitter)
}
})
while (true) {
const { redirectEvent, cancelEvent } = race({
redirectEvent: take(redirectChannel),
cancelEvent: take(ACTION_Y),
})
if (redirectEvent) {
yield put({
type: REDIRECT,
url,
})
} else {
redirectChannel.close()
return
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With