繁体   English   中英

在 redux-saga 应用程序中实现加载指示器的最佳方法是什么?

[英]What is the best way to implement Loading indicator in redux-saga app?

我正在使用(redux + redux-saga + typescript + typesafe-actions +ducks)开发应用程序

我正在考虑如何在 api 调用期间实现加载指示器。

这是我的结构

  state
    ducks
      common
        actions.ts
        reducers.ts
        sagas.ts
        selectors.ts
      group
        same as common/
      user
        same as common/

共同/行动

export const beginLoading = () => action(CommonActionTypes.BEGIN_LOADING);
export const endLoading = () => action(CommonActionTypes.END_LOADING);

团体/传奇

export function* handleFetchGroup() {
  try {
    const { group } = yield call(
      Api.fetchGroup
    );
    yield put(addGroup(group));
  } catch (err) {
    console.error(err);
  }
}

用户/传奇

export function* handleFetchUsers(action: addGroup) {
  try {
    yield take(ADD_GROUP);
    const users = yield call(
      Api.fetchUsers,
      action.payload.id
    );
    yield put(addUsers(users));
  } catch (err) {
    console.error(err);
  }
}

起初,我尝试了这个。

团体/传奇

export function* handleFetchGroup() {
  try {
    yield put(beginLoading()); // added
    const { group } = yield call(
      Api.fetchGroup
    );
    for(const group of groups) {
        yield put(addGroup(group));
    }
    yield put(endLoading()); // added
  } catch (err) {
    yield put(endLoading());
    console.error(err);
  }
}

在这种情况下,加载指示器仅在获取组数据期间显示。

所以我试过这个。

export function* handleFetchGroup() {
  try {
    yield put(beginLoading()); 
    const { groups } = yield call(
      Api.fetchGroups
    );
    for(const group of groups) {
        yield put(addGroup(group));
    }
  } catch (err) {
    yield put(endLoading());
    console.error(err);
  }
}

用户/传奇

export function* handleFetchUsers(action: addGroup) {
  try {
    yield take(ADD_GROUP);
    const users = yield call(
      Api.fetchUsers,
      action.payload.id
    );
    yield put(addUsers(users));
    yield put(endLoading()); // added
  } catch (err) {
    console.error(err);
    yield put(endLoading());
  }
}

在这种情况下,加载指示器在第一个 fetchUsers 完成时消失。

最后我尝试了这个。

export function* handleFetchGroup() {
  try {
    yield put(beginLoading());
    const { groups } = yield call(
      Api.fetchGroups
    );
    for(const group of groups) { 
        const users = yield call(Api.fetchUsers, group.id); // add
        yield put(addUsers(users));
    }
    yield put(endLoading());
  } catch (err) {
    yield put(endLoading());
    console.error(err);
  }
}

但在这种情况下,group saga 取决于用户实体。 所以我想避免这种情况,但我没有想出它。

你有什么解决办法吗??

我建议在用户状态和组状态下使用isLoading属性。 当为 group 发出 action beginLoading (我假设这个 action 将触发handleFetchGroup ),在 group reducer 中设置isLoading: true 组加载完成后,在组减速器中设置isLoading: false

为用户实现完全相同的逻辑。 因此,存在于用户减速器中的isLoading将被设置以响应用户的beginLoading等等。

在组分,其将显示负载指示器已经isLoading从组和isLoading从用户和显示负载指示每当以下两种是真实的。

例如(未测试,用作提示)

const LoadingIndicator: FC<{ user: UserState, group: GroupState }> = ({group, user}) => (
    group.isLoading || user.isLoading ? <div>Loading...</div> : null
}

export default connect(state => ({ user: state.user, group: state.group }), {})(LoadingIndicator)

我还看到您正在触发handleFetchUsers以响应ADD_GROUP 这也更好地解耦。 您可以考虑创建额外的 saga(例如loadAll ),它将触发用户加载以响应组加载完成。

例如(未测试)

function *loadAll() {
    yield put(BEGIN_GROUP_LOAD)
    yield takeEvery(GROUP_LOAD_FINISHED, function*(action) => {
        yield handleFetchUsers(action)
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM