我有一个连接到商店的容器,每秒更新一次:
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,
我只想学习如何以正确的方式做到这一点,任何有这方面知识的人能给我一些最佳实践提示吗?
答案 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
};