You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NX应用向共享库传props时,如何设置useAppDispatch的类型?

NX共享库通用登录组件:Redux解耦与类型处理方案

一、组件传参的优化方向

你不想让共享组件依赖全局store的思路完全正确,直接传递loginData确实不是最优解。更合理的做法是把共享组件做成纯UI受控组件:

  • 共享库的LoginForm只负责渲染表单、处理输入交互,对外暴露onSubmit(提交回调)、onInputChange(可选,输入变化回调),以及loading、error这类状态props
  • 应用层的Login组件专门对接Redux:从store读取状态、调用dispatch,把这些逻辑封装成回调传给LoginForm

这种模式下组件职责清晰,完全和Redux解耦,换项目复用的时候只需要替换回调逻辑就行,灵活性更强。

二、解决dispatch的类型问题(不用any,不依赖AppDispatch)

方案1:用Redux Toolkit的通用Dispatch类型

直接从@reduxjs/toolkit导入基础Dispatch类型,结合切片的action类型做限定:

// 共享库的LoginForm组件
import { Dispatch } from '@reduxjs/toolkit';
import { login } from './loginSlice'; // 你的登录切片action

type LoginFormProps = {
  // 推荐:只传提交回调,完全隐藏Redux细节
  onSubmit: (credentials: { username: string; password: string }) => void;
  // 如果一定要传dispatch,限定只能触发当前切片的action
  dispatch?: Dispatch<ReturnType<typeof login>>;
};

方案2:给切片专属定义Dispatch类型

如果你的登录切片有多个action(比如请求中、成功、失败),可以在切片文件里导出专属的Dispatch类型:

// 共享库/loginSlice.ts
import { createSlice, Dispatch, PayloadAction } from '@reduxjs/toolkit';

const loginSlice = createSlice({
  name: 'login',
  initialState: { loading: false, error: null },
  reducers: {
    loginRequest: (state, action: PayloadAction<{ username: string; password: string }>) => {
      state.loading = true;
    },
    loginSuccess: (state) => {
      state.loading = false;
    },
    loginFailure: (state, action: PayloadAction<string>) => {
      state.loading = false;
      state.error = action.payload;
    },
  },
});

export const { loginRequest, loginSuccess, loginFailure } = loginSlice.actions;
// 定义该切片所有action的类型
type LoginAction = ReturnType<typeof loginRequest | typeof loginSuccess | typeof loginFailure>;
// 导出专属的Dispatch类型
export type LoginDispatch = Dispatch<LoginAction>;

然后在共享组件里直接使用LoginDispatch:

import { LoginDispatch } from './loginSlice';

type LoginFormProps = {
  dispatch: LoginDispatch;
  loading: boolean;
  error: string | null;
};

这样组件只依赖自己切片的类型,完全不牵扯应用层的AppDispatch。

三、最推荐的使用方式(完全解耦)

在应用层的Login组件里把Redux逻辑封装成回调传给共享组件:

// 应用层/Login.tsx
import { useDispatch, useSelector } from 'react-redux';
import { LoginForm } from '@your-org/shared-ui';
import { loginRequest } from '@your-org/shared-features/login';
import { RootState } from './store';

export const Login = () => {
  const dispatch = useDispatch();
  const { loading, error } = useSelector((state: RootState) => state.login);

  const handleSubmit = (credentials: { username: string; password: string }) => {
    dispatch(loginRequest(credentials));
  };

  return (
    <LoginForm
      onSubmit={handleSubmit}
      loading={loading}
      error={error}
    />
  );
};

这种模式下,LoginForm完全不知道Redux的存在,只负责UI渲染和触发回调,复用性拉满,也符合前端组件设计的最佳实践。

内容的提问来源于stack exchange,提问作者Zahin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 17:23:35