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

在React Native中使用Inversify时如何避免服务定位器模式?

在React Native函数式组件中用InversifyJS实现Props式依赖注入

你遇到的问题本质是:Inversify的@lazyInject这类装饰器仅支持类组件,函数组件无法直接使用装饰器语法,而useInjection属于你想避免的服务定位器模式。下面是两种可行方案,实现通过props注入依赖的目标:

方案一:使用高阶组件(HOC)注入依赖

这是最直接符合你需求的方式——通过HOC将依赖从Inversify容器中取出,作为props传递给函数组件。

1. 定义接受依赖的组件

先调整组件的Props类型,把需要注入的服务明确加入Props:

import { Dispatch } from 'redux';
import { INavigationService } from './path-to-your-services';

// 组件原有基础Props
interface ISettingsBaseProps {
  navigation?: any;
}

// 需要注入的服务Props
interface ISettingsInjectedProps {
  navigationService: INavigationService;
}

// 合并后的完整Props类型
type ISettingsProps = ISettingsBaseProps & ISettingsInjectedProps & { dispatch: Dispatch };

const Settings = ({ dispatch, navigationService, ...baseProps }: ISettingsProps) => {
  return (
    <AuthenticatedView 
      {...{ ...baseProps, style: { justifyContent: 'flex-start', marginTop: '70%', alignItems: 'center' } }}
    >
      <Text>Settings!</Text>
      <Button 
        onPress={() => navigationService.navigate(baseProps, "Trade", dispatch)} 
        title="Trade" 
      />
    </AuthenticatedView>
  );
};

2. 创建注入用的HOC

编写一个高阶组件,从Inversify容器中解析服务,传递给目标组件:

import { container } from './path-to-your-inversify-container'; // 导入你的Inversify容器
import { TYPES } from './path-to-your-types';

// 通用注入HOC,可复用给其他组件
const withInjectedNavigationService = <P extends object>(
  Component: React.ComponentType<P & ISettingsInjectedProps>
) => {
  return (props: P) => {
    // 从容器中解析服务
    const navigationService = container.resolve<INavigationService>(TYPES.NavigationService);
    // 将服务作为props传递给组件
    return <Component {...props} navigationService={navigationService} />;
  };
};

3. 导出包裹后的组件

// 外部使用该组件时,无需手动传递navigationService
export default withInjectedNavigationService(Settings);

方案二:自定义注入Hook(进阶)

如果你更倾向于Hook风格,但又想尽量弱化服务定位器的感知,可以封装一个自定义Hook,不过本质还是基于容器解析:

import { container } from './path-to-your-inversify-container';
import { TYPES } from './path-to-your-types';
import { INavigationService } from './path-to-your-services';

// 自定义Hook,封装依赖解析逻辑
const useNavigationService = (): INavigationService => {
  return container.resolve<INavigationService>(TYPES.NavigationService);
};

// 在组件中使用
const Settings = (props: ISettingsBaseProps) => {
  const dispatch = useDispatch();
  const navigationService = useNavigationService(); // 替代useInjection

  return (
    // ... 组件内容和之前一致
  );
};

export default Settings;

注:这个方案虽然用了Hook,但本质还是服务定位器模式,只是做了封装。如果严格要求通过props注入,方案一更符合你的需求。

为什么@lazyInject不可行?

Inversify的装饰器(包括@lazyInject)是基于类的装饰器语法,只能用于类或类的成员(比如类组件的属性)。函数组件是普通JavaScript/TypeScript函数,不支持类装饰器语法,所以会报Decorators are not valid here错误,这个方向无法适配函数组件。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 09:25:23