启用 addEventListener 回调来做 put 的

Noi*_*art 5 redux-saga

我需要做一个全球性的addEventListener事情。我正在使用 react native 并且需要监听深度链接重定向事件。我无法弄清楚 redux-saga 的方法来做到这一点。我需要put从 addEventListener 中的回调启用 a 。

我目前做了导入store然后做的坏黑客,store.dispatch(...)如下所示:

import store from './flow-control'

Linking.addEventListener('url', ({ url }) => store.dispatch(_redir(url)));
Run Code Online (Sandbox Code Playgroud)

有没有一种 redux-saga 方法来做到这一点?

我希望把它放到 aa saga 也许:

function* reduxSaga() {

    const url = yield Linking.addEventListener('url', ({ url }) => ???);

}
Run Code Online (Sandbox Code Playgroud)

或者至少用这样的 put 替换 store.dispatch :

import { put } from 'redux-saga/effects'

Linking.addEventListener('url', ({ url }) => put(_redir(url)));
Run Code Online (Sandbox Code Playgroud)

使用 redux-saga 执行此操作的正确方法是什么?

Ale*_*lex 7

一种可能的解决方案是使用渠道。这是一个适合您的情况的示例:

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)
  }
}
Run Code Online (Sandbox Code Playgroud)

这里的想法是,我们将为 Linking.addEventListener 发出的每个 url 事件在通道上推送一个 REDIRECT 操作。

我们还必须启动另一个 saga 函数,该函数在 while 循环中侦听每个推送的操作 (watchRedirectChannel)。每次从通道中采取操作时,我们都会使用正常的yield put 来告诉 redux-saga 应调度该操作。

这是使用 API 的示例eventChannel

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
    }
  }
}
Run Code Online (Sandbox Code Playgroud)