使用包含promise

时间:2016-12-01 11:05:51

标签: javascript reactjs redux es6-promise reselect

我有一个连接到商店的容器,每秒更新一次:

return ({ match, ui }, { matchId }) => ({
    value: match.getIn([matchId, 'masterCurrentTime'], 0), // about every second
    min: ui.get('seekStart'),
    max: ui.get('seekEnd'),
    highlightList: selectHighlights(matchId) // i only want to do this on first render
  });

然而,其中一个属性(highlightList)执行以下两项操作之一:

1)从sessionStorage

返回一个值

2)下载文件,将其保存到sessionStorage然后返回

当然,我不希望每一秒都这样做,只是第一次。

我创建了一个像这样的选择器

const selectHighlights = createSelector(
    matchId => matchId,
    matchId => {
      if (matchId !== null) {
        getTimelineWithFilter(matchId, ['round_start'])
          .then(timeline => {
            console.log(timeline);
            return timeline;
          })
          .catch(error => {
            throw new Error('failed to load highlights', error);
          });
      }

      return null;
    }
  );

但它不起作用,它不会被渲染。 但是,如果我做一个替代版本,我将结果存储在一个变量中,然后查询它,那就可以了。它只运行一次并按照我喜欢的方式执行

// highlightList: currentTimeline === undefined ? loadHighlights(matchId) : currentTimeline,

我只想学习如何以正确的方式做到这一点,任何有这方面知识的人能给我一些最佳实践提示吗?

1 个答案:

答案 0 :(得分:1)

如何在React-Redux应用中处理承诺?

假设您有一个操作创建者,用于从某些API获取数据。您将从组件中调度操作(在加载/单击/在其他事件上)。

export function loadData(key) {
  return {
    types: [LOAD_DATA, LOAD_DATA_SUCCESS, LOAD_DATA_FAIL]
    promise: () => fetch(...), // API call that returns a promise
    key,
  }
}

现在为基于承诺的操作创建middleware。创建store时确保applyMiddleware

  

中间件最常见的用例是支持异步   没有太多样板代码或对库的依赖的动作   像Rx。它通过让您再发送异步操作来实现   正常行动。

export default function clientMiddleware() {
  return ({ dispatch, getState }) => next => (action) => {
    if (typeof action === 'function') {
      return action(dispatch, getState);
    }

    const { promise, types, ...rest } = action;

    if (!promise) {
      return next(action);
    }

    const [REQUEST, SUCCESS, FAILURE] = types;

    next({ ...rest, type: REQUEST });

    const actionPromise = promise();
    actionPromise
      .then(result => next({ ...rest, result, type: SUCCESS }))
      .catch(error => next({ ...rest, error, type: FAILURE }));

    return actionPromise;
  };
}

最后这是 initialState

const initialState = {
  isLoading: false,
  isLoaded: false,
  data: {},
  error: null,
};

redurs

case LOAD_DATA:
  return {
    ...state,
    isLoading: true
  };

case LOAD_DATA_SUCCESS:
  return {
    ...state,
    isLoading: false,
    isLoaded: true,
    data: action.result,
  };

case LOAD_DATA_FAIL:
  return {
    ...state,
    isLoading: false,
    isLoaded: false,
    error: action.error
  };