【问题标题】:Problem with metronic react theme to typescriptMetronic反应主题对打字稿的问题
【发布时间】:2021-03-04 10:11:53
【问题描述】:

它是 v7.1.7,在 react redux 中使用 saga 中间件,并且是用 JavaScript 设计的,而不是 Typescript。 我在 authRedux.ts 中的 saga 生成器有问题(原始文件是 authRedux.js)。 authRedux.js 中没有错误,但如果我将其更改为 .ts,则会出现 2 个错误。

src/app/modules/Auth/_redux/authRedux.ts

import { AnyAction } from '@reduxjs/toolkit';
import { persistReducer } from 'redux-persist';
import storage from 'redux-persist/lib/storage';
import { put, takeLatest } from 'redux-saga/effects';
import { getUserByToken } from './authCrud';

export const actionTypes = {
  Login: '[Login] Action',
  Logout: '[Logout] Action',
  Register: '[Register] Action',
  UserRequested: '[Request User] Action',
  UserLoaded: '[Load User] Auth API',
  SetUser: '[Set User] Action',
};

type TUser = string | undefined;
type TAuthToken = string | undefined;

export interface IAuth {
  user: TUser;
  authToken: TAuthToken;
}

const initialAuthState: IAuth = {
  user: undefined,
  authToken: undefined,
};

export const reducer = persistReducer<IAuth, AnyAction>(
  { storage, key: 'v713-demo1-auth', whitelist: ['user', 'authToken'] },
  (state: IAuth = initialAuthState, action: AnyAction) => {
    switch (action.type) {
      case actionTypes.Login: {
        const { authToken } = action.payload;
        return { authToken, user: undefined };
      }

      case actionTypes.Register: {
        const { authToken } = action.payload;
        return { authToken, user: undefined };
      }

      case actionTypes.Logout: {
        // TODO: Change this code. Actions in reducer aren't allowed.
        return initialAuthState;
      }

      case actionTypes.UserLoaded: {
        const { user } = action.payload;
        return { ...state, user };
      }

      case actionTypes.SetUser: {
        const { user } = action.payload;
        return { ...state, user };
      }

      default:
        return state;
    }
  },
);

export const actions = {
  login: (authToken: TAuthToken) => ({
    type: actionTypes.Login,
    payload: { authToken },
  }),
  register: (authToken: TAuthToken) => ({
    type: actionTypes.Register,
    payload: { authToken },
  }),
  logout: () => ({ type: actionTypes.Logout }),
  requestUser: (user: TUser) => ({
    type: actionTypes.UserRequested,
    payload: { user },
  }),
  fulfillUser: (user: TUser) => ({
    type: actionTypes.UserLoaded,
    payload: { user },
  }),
  setUser: (user: TUser) => ({ type: actionTypes.SetUser, payload: { user } }),
};

export function* saga() {
  yield takeLatest(actionTypes.Login, function* loginSaga() {
    //here is the first error. TypeScript error: Expected 1 arguments, but got 0.  TS2554
    yield put(actions.requestUser());
  });

  yield takeLatest(actionTypes.Register, function* registerSaga() {
    //here is the second error. TypeScript error: Expected 1 arguments, but got 0.  TS2554
    yield put(actions.requestUser());
  });

  yield takeLatest(actionTypes.UserRequested, function* userRequested() {
    const { data: user } = yield getUserByToken();
    yield put(actions.fulfillUser(user));
  });
}

我在出现错误的地方添加了注释。它在 saga() 函数中,它是 saga 生成器。 我该如何解决?

【问题讨论】:

    标签: reactjs typescript authentication redux saga


    【解决方案1】:

    您的requestUser 动作创建者将user 对象作为参数:

    requestUser: (user: TUser) => ({
      type: actionTypes.UserRequested,
      payload: { user },
    }),
    

    当切换到.ts 时,typescript 能够检测到缺少所需参数的函数调用。你正在从你的 saga 中调度这个 requestUser 动作创建者,而没有传递一个 user 参数:

    // TypeScript error: Expected 1 arguments, but got 0.  TS2554
    yield put(actions.requestUser());
    

    您已在您的 userRequested/fulfillUser 传奇中正确处理了此问题,您可以从 getUserByToken 访问 user 对象,然后将其传递给您的动作创建者。您需要在您的loginSagaregisterSaga 中执行相同或类似操作才能正确调用actions.requestUser

    【讨论】:

    • 感谢您的回答。但我不明白为什么这个 metronic 主题缺少论点。你说我需要做与用户请求的传奇相同或相似的事情,但我怎样才能获得用户?登录或注册前没有令牌。我可以删除这个传奇,但我想知道为什么 metronic 缺少这个论点。或者如何详细修复它。
    • 好的,我不太明白这不是您要转换为 TS 的代码。如果他们在没有user 的情况下调用requestUser,那么requestUser 的类型应该将user 作为可选参数requestUser: (user?: TUser) =&gt; ({ 或者根本没有user 作为参数?还有其他地方可以拨打requestUser(user)吗?此操作仅由 saga 使用,reducer 不使用,所以应该没问题。
    • 我想我可以在 yield put() 上方插入必要的代码。例如,http axios 调用获取授权用户名并将其设置为 requestUser() 的参数。事实上,他们只有在注册或登录时才会收到 access_token。我更改了此代码以接收带有用户名的令牌。但我认为他们的意思是我应该将它插入到 saga 中间件中。谢谢。
    猜你喜欢
    • 1970-01-01
    • 2017-09-26
    • 2020-01-29
    • 1970-01-01
    • 2021-10-20
    • 2020-01-13
    • 2020-11-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多