reactjs - 打字稿扩展 React.Component
问题描述
@tl;博士
我想在 Typescript 中不使用 HOC / Providers 的情况下扩展 React 组件
好的,这就是交易...
在我的工作场所,我们曾经使用 Vue 和纯 JS...然后我们决定迁移到使用 Typescript 的 React...
我们使用的技术: - React - Typescript - Redux - Redux-Saga
问题是,回到 Vue,我们可以声明如下内容:
Vue.use(Auth)
在每个 .vue 文件中,在 script 标签内,我们可以调用如下内容:
this.$auth
并有权访问授权方法。
我想要做的是......创建一个 ReactComponent 的扩展,我已经创建了一些我的大部分组件将使用的方法......比如:
- auth // 检查用户是否被认证,如果是,获取用户信息
- route // 给我当前的路线,包括查询参数、重定向等……这是我现在唯一能想到的两个。
我想在我的 .ts 文件中有这样的内容:
interface MyProps {
route: any // don't remember the correct Type
}
class MyComponent<T,S = {},SS = {}> extends React.Component<T,S,SS> {
$route = () => {
this.props.route
}
}
export default withRouter(MyComponent)
并像这样在我的应用程序中调用它:
inteface AnotherProps {
}
class AnotherComponent extends MyComponent<AnotherProps> {
render() {
if(this.$route().location.pathname == "/") {
return <div>Root</div>
} else {
return <div>Not Root</div>
}
}
}
到目前为止我尝试过的
HOC(高阶组件)
我可以使用 HOC 实现我想要的,但问题是......如果可能的话,我想要两件事。
- 要将这个新属性存储在this而不是this.props,如果可以使用 HOC,我不知道如何
- 使用 HOC,我还需要导入基本 Props,如下所示:
import BaseProps from Outterspace;
inteface AnotherProps extends BaseProps{
}
我希望MyComponent和AnotherComponent内部的逻辑尽可能相互独立......
提供者
与 HOC 相同,我需要将我想要的属性作为道具传递,并且需要扩展我的道具接口。
[编辑]
装饰器
有人在评论中说我可以尝试使用 Decoratos,虽然我确实阅读了文档并且听起来很有希望......文档的最后一行让我有点担心..
注意装饰器元数据是一项实验性功能,可能会在未来的版本中引入重大更改。
非常感谢你读到这里^^
解决方案
如果您使用的是打字稿,那么您可以创建装饰器。
您可以在类顶部调用装饰器并添加属性。
@YourAuthDecorator({
'propertiesForconfiguration': 'value'
})
export class ReactClass extends ReactComponent {}
例子:
function abc() {
return {};
}
export function Auth() {
console.log("-- decorator function invoked --");
return function (constructor: Function){
console.log(constructor, 'called');
constructor.prototype.$auth = abc();
}
}
class Sample {
public prop = 'sample'
}
@Auth()
export class Content extends Sample {
}
export const a = new Content();
装饰器的功能是将各种属性附加到此实例,从而为您提供对各种功能/属性(如身份验证)的访问权限
您可以在此处阅读有关装饰器的更多信息。 https://www.typescriptlang.org/docs/handbook/decorators.html
推荐阅读
- javascript - 构建一个“记录/收集”我自己的传入消息并以反应原生方式显示它们的应用程序
- r - 计算每个 ID 在过去一年内的响应总和
- javascript - 何时调用 RTCPeerConnection.onIcecandidate() 事件?
- javascript - 无法启动 in-view.js
- reactjs - 使用 react map gl 库更改地图样式后如何重新初始化源和图层
- reactjs - 使用分页搜索和过滤
- java - 运行gradlew测试时如何限制某些包的日志?
- google-cloud-platform - Pulumi GCP Manage Oauth2.0 Client Id Redirect URI
- .net-core - 使用 dotnet 核心的 OneSignal 推送通知返回 NULL ID
- geopandas - 将点分配给最近的多边形