React Redux async数据同步然后重新渲染视图



我有许多操作和为不同内容类型的修复器设置,例如页面,活动和场地。这些操作和还原器获取了通过另一个称为同步的动作将其保存到AsyncStorage的数据,并将其放入商店中。

Sync执行一个异步呼叫对内容的调用,并检索任何新/更新/删除的条目,然后将其保存到AsyncStorage

在异步呼叫完成后,确保正确渲染视图的最佳方法是什么?

syncReducer是否应该将数据合并到通常会被pagesReducervenuesReducer等撤出的商店,还是应该在完成syncReducer之后发出某种事件?

数据被异步地吸入离线查看并保持快速的速度,因此我真的不想在渲染之前等待同步。

data/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;

最后,我能够通过将其他操作导入我的同步操作来解决此问题,并根据需要更新数据来派遣。

import { getEvents } from './getEvents';
import { getPages } from './getPages';
import { getVenues } from './getVenues';
export function sync() {
  return dispatch => {
    dispatch(syncRequestedAction());
    return cache
      .sync()
      .then(results => {
        dispatch(syncFulfilledAction());
        if (results.includes('event')) {
          dispatch(getEvents());
        }
        if (results.includes('page')) {
          dispatch(getPages());
        }
        if (results.includes('venue')) {
          dispatch(getSettings());
        }
      })
      .catch(error => {
        console.log(error);
        dispatch(syncRejectedAction());
      });
  };
}

您的同步操作应该是一个thunk函数(redux中间件),它可以使呼吁符合满足,解决诺言并包含数据或错误。然后,您可以派遣其他操作,或者将数据减少到商店中的操作。

在您要重新渲染的每个组件上(基于我们刚刚派遣和减少的操作在商店中更新的数据),如果您有connect(mapStateToProps, mapDispatchToProps),并且已将商店的那些部分包括在MSTP中,这些Props将更新将重新渲染组件。

,您甚至可以通过创建另一个动作来派遣并降低到商店的某些部分时,甚至可以更明确地解决数据的分辨率。

因此,当您拨打电话时,您可以派遣" fetch_in_progress',然后'fetch_error'或'fetch_success',如果那是mapstateToprops'的组件,则可以选择在showscomponentupdate()中选择它,并根据位置进行评估。该过程是,您可以根据要恢复归还的方式返回true或false。您也可以强制呈现componentWillReceiveProps。我首先只依靠道具在必要时进行更改和添加。

您应该使用 redux persist 进行这种事情,它支持Asyncstorage和一系列其他选项。

https://github.com/rt2zz/redux-persist

操作和还原器应只是为了更新Redux商店而设计。任何其他动作都称为副作用,应在中间件或商店增强器中进行管理。

我强烈建议您不要使用redux-thunk,对于几件事而言,它对它有用的几件事太强大了,并且很容易创建无与伦比的反胶合代码,因为它模糊了动作和中间件代码之间的边界。

如果您认为您需要使用Redux-thunk首先查看它们是否已经是您需要的中间件,并且如果不了解Redux-Sagas。

最新更新