如何使用注入的属性实例化 React 组件

How to instantiate react component with injected properties

我正在将一个反应项目从 redux 转换为 mobx,我遇到了以下问题:我在 redux 中使用 container/presenter 模式,这意味着使用 redux "connect" 函数,像这样:

 export default connect(mapStateToProps, mapDispatchToProps)(Leads);

我遇到的问题是没有等效的 mobx 函数,因此,我尝试在容器中简单地创建一个组件实例。类似于:

render() {
  return (
    <MyComponent
      store={mystore}
    />
  );
}

不幸的是,这不起作用,因为 MyComponent 已经从 react-router 注入了属性,就像这样:

class MyComponent extends React.Component<ReportProps & RouteComponentProps<ReportProps>> {

  constructor(public routeProps: ReportProps & RouteComponentProps<ReportProps>) {
    super(routeProps);
  }...

我尝试摆脱容器的概念,但同样的问题出现在其他地方,因为我使用了 mobx-react @inject 装饰器。例如,我有一个这样的组件:

export interface AddressProps {
  report: IReportStore;
}

@inject((rootStore: RootStore) => ({
  report: rootStore.report
}))
@observer
class Address extends React.Component<AddressProps> {
...

如果我随后尝试在某处使用我的组件,typescript 会抱怨我没有通过所需的 属性(在本例中为报告),即使我不需要,因为我' m 注入属性。

我想我一定遗漏了一些基本的东西,因为这是对 mobx 的相当直接的使用。或者也许这只是一个打字稿问题......?如果是这样,有什么想法可以解决或解决它吗?

提前致谢, 乔纳森

围绕 mobx 注入方法存在很多问题。

最初的想法是 return 一个 Partial<TProps> 但你不能在不丢失原始 Class 的情况下输入:React.Component<Partial<TProps>,TState> != YourComponent - 设置属性。

在此处阅读讨论的问题:https://github.com/mobxjs/mobx-react/issues/256

简单的解决方案

在 props 中使用可选参数并将它们设置在 getter 属性:

interface AppProps {
    store?: SDtore;
}

class App {
  get store(): TimeEntryStore {
    return this.props.store as Store;
  }
  method(){
     this.store;///
  }
}

其他解决方案

如果你想保留你需要的参数(例如:为了在 mobx 之外使用组件等)。

您可以考虑将组件转换为 React.Component<TPropsReduced,State>,其中 TPropsReduced 是一个自定义接口,在注入后具有所需的道具。

缺点是:

  • 转换时失去类型安全性(例如,如果您在接口属性中创建 mistakes/typo。(可以通过 extending/subclassing 接口解决。
  • 丢失方法调用。您将不再在组件上使用类型化方法(例如:当您使用 ref={()=>} 时),但无论如何都不建议使用它。

示例:

interface AddressPropsMobx {
}

interface AddressProps extends AddressPropsMobx {
  report: IReportStore;
}



//Pure react component
class Address extends React.Component<AddressProps> {}

// Mobx version:
const MobxAddress = inject((rootStore: RootStore) => ({
  report: rootStore.report
}))(observer(Address)) as React.Component<AddressPropsMobx>;  //unsafe cast