【问题标题】:Redux-Saga behavior patternRedux-Saga 行为模式
【发布时间】:2017-12-11 12:46:06
【问题描述】:

这样的传奇效果很好:

function* getPosition() {
  yield navigator.geolocation.getCurrentPosition(function(pos) {
    console.log(`I am getPosition: ${pos.coords.latitude}, ${pos.coords.longitude}`);
  });
}

但我需要 Redux 状态树中的坐标。所以,我尝试了一些模式,但它们都不起作用。 1) 没有办法让变量超出 getCurrentPosition 范围

function* getPosition() {
  let position = {};
  yield navigator.geolocation.getCurrentPosition(function(pos) {
    position = pos;
  });
  // either
  console.log(`I am getPosition: ${position.coords.latitude}, ${position.coords.longitude}`);
  // or
  yield console.log(`I am getPosition: ${position.coords.latitude}, ${position.coords.longitude}`);
  // Any of two is undefined
}

2) 没有办法返回和赋值:

function* getPosition() {
  const position = yield navigator.geolocation.getCurrentPosition(function(pos) {
    return pos;
  });
  yield console.log(`I am getPosition: ${position.coords.latitude}, ${position.coords.longitude}`);
}

3) 方法put无效:

function* getPosition() {
  yield navigator.geolocation.getCurrentPosition(function(pos) {
    // Pos fetched
    console.log(`I am getPosition: ${pos.coords.latitude}, ${pos.coords.longitude}`);
    // Nothing happens. State is empty object.
    put({
      type: LOCATION_SET_POSITION,
      pos
    });
  });
}

locationReducer 位于 rootReducer 内部,因为其他工作的 reducer 是:

locationReducer.js
export function locationReducer(state = {}, action) {
  switch (action.type) {
    case LOCATION_SET_POSITION:
      return action.pos
    default:
      return state;
  }
}

而且我没有 actionCreater。据我了解,put 方法都 调度一个动作并设置 actionCreator。 如何将坐标放入状态树?

【问题讨论】:

  • 你没有得到答案的原因是因为你没有使用任何效果,你提到了一些关于put 效果的东西,但是,我看不到你在哪里使用它。记得使用call 来管理异步操作,否则,它不是传奇,它只是一个函数生成器......最好

标签: javascript redux-saga


【解决方案1】:

您的问题是 geolocation.getCurrentPosition 是异步的,但它是成功/错误回调样式,而您需要将它作为一个承诺提供给 redux-saga

function* getPositionSaga() {
    const getCurrentPosition = () => new Promise(
      (resolve, reject) => navigator.geolocation.getCurrentPosition(resolve, reject)
    )
    const pos = yield call(getCurrentPosition)
    yield put({type: LOCATION_SET_POSITION, pos})
}

这里我们将getCurrentPosition包装成一个返回Promise<Position>的函数

call 是一个 redux-saga 效果,如果给它的函数返回一个 Promise,它只会在该 Promise 被履行时才产生,并将履行的价值返回到你的 saga 中以供进一步使用。

put 是一个最终会通过 redux 调度给定动作对象的效果

任何 redux-saga 效果都必须从生成器产生,而不是直接调用,因为它们只返回一个简单的指令对象给 redux-saga 中间件执行器(而不是立即实际执行副作用)。执行器只能在生成器产生时访问和控制它们,因此在示例 3 中的回调中使用它们不会像您期望的那样工作

【讨论】:

  • 稍微提醒一下,promise 返回的pos 值是一个复杂的 Javascript 对象,它需要一些转换才能被相应的 reducer 存储。
猜你喜欢
  • 2021-11-14
  • 2018-02-24
  • 2017-04-26
  • 2017-05-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-20
相关资源
最近更新 更多