【发布时间】:2017-11-29 14:05:44
【问题描述】:
我为不同的内容类型设置了许多操作和缩减程序,例如页面、活动和场地。这些 action 和 reducer 通过另一个名为 sync 的 action 获取已保存到 AsyncStorage 的数据,并将其放入存储中。
Sync 对 Contentful 执行异步调用并检索任何新的/更新的/删除的条目,然后我将其保存到 AsyncStorage。
在异步调用完成后,确保正确重新呈现视图的最佳方法是什么?
syncReducer 是否应该将通常由pagesReducer、venuesReducer 等拉出的数据合并到存储中,还是应该在syncReducer 完成后发出某种事件?
数据被异步拉入以供离线查看和保持快速,所以我真的不想在渲染前等待同步。
数据/sync.js
import { AsyncStorage } from 'react-native';
import database from './database';
const cache = {
getByType: async (query) => {
return new Promise(async(resolve, reject) => {
// Get results from AsyncStorage
resolve(results);
});
},
sync: async () => {
return new Promise(async(resolve, reject) => {
database
.sync(options)
.then(async results => {
// Save results to AsyncStorage
resolve(results);
});
});
}
};
export default cache;
actions/sync.js
import actionTypes from '../constants/actionTypes';
import cache from '../data/cache';
export function sync() {
return dispatch => {
dispatch(syncRequestedAction());
return cache
.sync()
.then(() => {
dispatch(syncFulfilledAction());
})
.catch(error => {
console.log(error);
dispatch(syncRejectedAction());
});
};
}
function syncRequestedAction() {
return {
type: actionTypes.SyncRequested
};
}
function syncRejectedAction() {
return {
type: actionTypes.SyncRejected
};
}
function syncFulfilledAction(data) {
return {
type: actionTypes.SyncFulfilled,
data
};
}
actions/getPages.js
import actionTypes from '../constants/actionTypes';
import cache from '../data/cache';
export function getPages() {
return dispatch => {
dispatch(getPagesRequestedAction());
return cache
.getByType('page')
.then(results => {
dispatch(getPagesFulfilledAction(results));
})
.catch(error => {
console.log(error);
dispatch(getPagesRejectedAction());
});
};
}
function getPagesRequestedAction() {
return {
type: actionTypes.GetPagesRequested
};
}
function getPagesRejectedAction() {
return {
type: actionTypes.GetPagesRejected
};
}
function getPagesFulfilledAction(settings) {
return {
type: actionTypes.GetPagesFulfilled,
pages
};
}
reducers/pagesReducer.js
import { merge } from 'lodash';
import actionTypes from '../constants/actionTypes';
const pagesReducer = (state = {}, action) => {
switch (action.type) {
case actionTypes.GetPagesRequested: {
return merge({}, state, { loading: true });
}
case actionTypes.GetPagesRejected: {
return merge({}, state, { error: 'Error getting pages', loading: false });
}
case actionTypes.GetPagesFulfilled: {
const merged = merge({}, state, { error: false, loading: false });
return { ...merged, data: action.pages };
}
default:
return state;
}
};
export default pagesReducer;
【问题讨论】:
-
能否添加一些真实代码或伪代码来说明数据流是什么?
-
你需要让你的组件响应prop的变化。在数据可用之前,数据同步不应更改道具。这意味着您应该在异步 redux 操作中完成所有这些操作(我更喜欢使用 sagas)。这样,一旦所有异步工作完成,它只需使用准备好的数据更新存储一次。所以你的组件真的可以是“哑巴”/“纯”的,只是基于道具渲染。
-
@markerikson 如果有帮助的话,我已经用一些精简的代码更新了我的问题。
标签: react-native react-redux redux-thunk