问题显示使用redux和react的全局微调器

时间:2020-06-30 04:39:19

标签: reactjs redux react-redux spinner

我的index.jsx页面中有一个按钮,用于调度激活动作

<StickyButton type="button" onClick={() => dispatch(activate(values))}>
  <span>{t("share.button.continue")}</span>
</StickyButton>;

然后执行此操作,调度另一个操作调用isRequesting(),我在微调器中使用它来显示微调器,然后在authService中调用一个方法来激活用户:

export const activate = (model) => async (dispatch) => {
  await dispatch(isRequesting());
  authService
    .activate(model)
    .then(async (result) => {
      authService.setSignedUp();
      await dispatch(fetchProfile());
      await dispatch(isRequested());
      history.push(`${routes.sign_up.base}${routes.sign_up.activated}`);
    })
    .catch((error) => {
      dispatch(errorOccurred());
    });
};

和authService激活功能为:

function activate(model) {

  let request = {
    lang: encryptService.aesStaticEncrypt(localeService.getActiveLanguage()),
    ver: encryptService.aesStaticEncrypt(config.app_version),
    phoneNumber: encryptService.aesStaticEncrypt(utilService.formatMobileWithPrefix(userService.getMobile())),
    invoice: encryptService.aesStaticEncrypt(utilService.getRandomDigit()),
    value: {
      activationCode: encryptService.aesStaticEncrypt(utilService.formatActivationCode(model.activation_code)),
    },
  };
  return api
    .post(`${config.apiUrl}/GATEWAY/ACTIVATIONGATEWAY/V1/Activate`, request)
    .then(async (result) => {
      return Promise.resolve(result);
    })
    .catch((error) => {
      utilService.handleError(error);
      return Promise.reject(error);
    });
}

和微调组件:

export const FullPageSpinner = () => {
  const { isRequesting } = useSelector((state) => state.request);
  console.log("FullPageSpinner");
  console.log(isRequesting);
  return (
    <div
      css={{
        position: "fixed",
        width: "100%",
        height: "100%",
        display: "flex",
        justifyContent: "center",
        fontSize: "3rem",
        top: 0,
        left: 0,
        right: 0,
        bottom: 0,
        backgroundColor: "#00000038",
        opacity: isRequesting ? 1 : 0,
        zIndex: isRequesting ? "9999999" : "-1",
      }}
    >
      <div css={{ alignSelf: "center", color: "#3e3e3e" }}>
        <Spinner />
      </div>
    </div>
  );
};

请求简化程​​序代码:

import * as types from "../actionTypes/request";

const initialState = {
  isRequesting: false,
  isRequested: false,
};

export default function requestReducer(state = initialState, action) {
  if (action.type === types.IsRequesting) {
    return {
      ...state,
      isRequesting: true,
      isRequested: false
    };
  }
  if (action.type === types.IsRequested) {
    return {
      ...state,
      isRequesting: false,
      isRequested: true
    };
  }
  if (action.type === types.ErrorOccurred) {
    return {
      ...state,
      isRequesting: false,
      isRequested: true
    };
  }
  return state;
}

根减速器:

import { combineReducers } from "redux";
import profileReducer from "./profile";
import requestReducer from "./request";
import appReducer from "./app";


const rootReducer = combineReducers({
  profile: profileReducer,
  request: requestReducer,
  app: appReducer,
});

export default rootReducer;

并创建商店:

const store = createStore(
  reducer,
  compose(
    applyMiddleware(thunk),
    (window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__()) || compose
  )
);

请求动作:

import * as request_types from "../actionTypes/request";

export const isRequesting = () => {
  console.log("isRequesting");
  return {
    type: request_types.IsRequesting,
  };
};

export const isRequested = (messages) => {
  console.log("isRequested");
  return {
    type: request_types.IsRequested,
    payload: messages,
  };
};

请求减少器:

const initialState = {
  isRequesting: false,
  isRequested: false,
};

export default function requestReducer(state = initialState, action) {
  if (action.type === types.IsRequesting) {
    return {
      ...state,
      isRequesting: true,
      isRequested: false
    };
  }
  if (action.type === types.IsRequested) {
    toastService.notify(action.payload);
    return {
      ...state,
      isRequesting: false,
      isRequested: true
    };
  }
  if (action.type === types.ErrorOccurred) {
    return {
      ...state,
      isRequesting: false,
      isRequested: true
    };
  }
  return state;
}

和AppComponent,我将FullPageSpinner放置在基于isRequesting的位置

const App = () => {
  const { ltr } = useSelector((state) => state.language);
  return (
    <React.Fragment>
      <Routing />
      <ToastContainer
        position="bottom-center"
        autoClose={config.toast_auto_close}
        transition={Flip}
        {...(!ltr && { rtl: true })}
      />
      <FullPageSpinner />
    </React.Fragment>
  );
};

export default App;

问题是当我调度isRequesting()时,状态正在更改,但微调框未显示,并且它等待authService.activate函数的响应,这可能需要一些时间才能返回。 我希望微调器在调度isRequesting()之后立即显示,而不要等待

的响应

1 个答案:

答案 0 :(得分:1)

尝试从激活操作创建者中删除不必要的异步/等待操作:

export const activate = (model) => (dispatch) => { // async here is not necessary
  dispatch(isRequesting()); // await here is not necessary
  authService
    .activate(model)
    .then(async (result) => {
      authService.setSignedUp();
      await dispatch(fetchProfile());
      dispatch(isRequested()); // await here is not necessary
      history.push(`${routes.sign_up.base}${routes.sign_up.activated}`);
    })
    .catch((error) => {
      dispatch(errorOccurred());
    });
};

编辑:

我看了您添加到沙箱中的示例,发现您在authService.activate()的实现中不是异步的。

我在此处提供了修复程序: https://stackblitz.com/edit/react-xplsqp?file=services/auth.js

您原来的authService.activate()可能正在阻塞,并且也并非异步。 因此,请检查您的api.post是否异步。我还建议您对代码进行一些改进(请查看我的评论):

//autService.activate
//...
 return api
    .post(`${config.apiUrl}/GATEWAY/ACTIVATIONGATEWAY/V1/Activate`, request)
    .then(async (result) => { // remove async from here
      return Promise.resolve(result); // do not use Promise.resolve, just "return result;" is correct
    })
    .catch((error) => {
      utilService.handleError(error);
      return Promise.reject(error); // do not use Promise.reject here, if you want to recatch this error in next chain just "throw error;" instead
    });
// ...
相关问题