定义Metas

Metas是Meta的集合。假设一个Request Action需要同时执行多次,并且业务上需要根据传入Action的参数获取不同的meta信息。如果我们仍然用Meta存储,因为请求是异步的,meta的数据也会覆盖,最终导致数据出错。

此时,我们可以使用payload解决这个问题。

  1. import { Model } from '@redux-model/web';
  2. import { $api } from './ApiService';
  3.  
  4. interface Response {
  5. id: number;
  6. name: string;
  7. }
  8.  
  9. type Data = Partial<{
  10. [key: string]: Response;
  11. }>;
  12.  
  13. class ThirdModel extends Model<Data> {
  14. getProfile = service.get((userId: number) => {
  15. return this
  16. .uri('...')
  17. .payload({ userId })
  18. .metaKey('userId');
  19. });
  20.  
  21. protected initReducer(): Data {
  22. return {};
  23. }
  24. }
  25.  
  26. export const thirdModel = new ThirdModel();

metaKey 设置为payload的存在的一个属性名时,metas就会被启用。我们只要在使用时传入 payload 对应的值时,就能拿到Meta对象。

  1. const userId = 3;
  2.  
  3. thirdModel.getProfile(userId);
  4.  
  5. const meta = thirdModel.getProfile.metas.pick(userId);

使用Loadings

同样地,Metas也配置了快捷获取loading的方法

  1. const loadings = thirdModel.getProfile.loadings;
  2.  
  3. const userId = 3;
  4. const loading = thirdModel.getProfile.loadings.pick(userId);

在Hooks中使用

在React的hooks组件中,我们需要使用use前缀去获取metas

  1. const userId = 3;
  2.  
  3. const myMetas = thirdModel.getProfile.useMetas();
  4.  
  5. const myMeta = myMetas.pick(userId);
  6. const myMeta = thirdModel.getProfile.useMetas(userId);
  7.  
  8. // 性能 A+
  9. const myCode = thirdModel.getProfile.useMetas(userId, 'businessCode');
  10. // 性能 B+
  11. const myCode = thirdModel.getProfile.useMetas(userId).businessCode;
  12. // 性能 C+
  13. const myCode = thirdModel.getProfile.useMetas().pick(userId).businessCode;
  14.  
  15.  
  16.  
  17. const loadings = thirdModel.getProfile.useLoadings();
  18.  
  19. const loading = loadings.pick(userId);
  20. const loading = thirdModel.getProfile.useLoadings(userId);

Payload除了可以创建Metas之外,还有一个作用,就是在改变reducer时,可以根据payload传入的信息来决定变更策略。

  1. getProfile = $api.get(() => {
  2. return this
  3. .uri('')
  4. .onSuccess((state, action) => {
  5. state[action.payload.userId] = action.response;
  6. });
  7. });