如何使用注入的属性实例化 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
我正在将一个反应项目从 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