Javascript 覆盖反应组件';s原型法

Javascript 覆盖反应组件';s原型法,javascript,reactjs,Javascript,Reactjs,假设我有以下React组件类: class SayHello extends React.Component { constructor(props) { super(props); this.handleOnClick = this.handleOnClick.bind(this); } render() { return <div onClick={this.handleOnClick}>Click Me

假设我有以下React组件类:

class SayHello extends React.Component {
    constructor(props) {
        super(props);

        this.handleOnClick = this.handleOnClick.bind(this);
    }

    render() {
        return <div onClick={this.handleOnClick}>Click Me</div>;
    }

    handleOnClick() {
        console.log("clicked");
    }
}
类SayHello扩展了React.Component{
建造师(道具){
超级(道具);
this.handleOnClick=this.handleOnClick.bind(this);
}
render(){
返回点击我;
}
handleOnClick(){
控制台日志(“单击”);
}
}
我想做的是创建一个更高阶的组件,它知道
SayHello
中的
handleOnClick
,但是在调用
SayHello
handleOnClick
之前,我想让它先执行我传入的一些代码(即,我想运行在我的服务器上记录一些东西的代码)

这样做有反应模式吗

编辑:

我想在这里提供更多的上下文。我希望我的高阶组件在调用哪些方法方面是动态的。例如,有时它可能是
handleOnClick
,但有时它可能是
handleOnSomethingElse

A是一个接受组件参数并返回新组件的函数

此函数返回具有修饰的
handleClick
方法的组件:

// A higher-order component that runs some code before
// the given component's `handleClick` method
function wrapHello(componentClass) {
  return class wrapped extends componentClass {
    beforeHandleClick() {
      console.log("I run first!")
    }

    handleClick(...args) {
      this.beforeHandleClick()
      super.handleClick(...args)
    }
  }
}
是整洁的,因为它根本没有反应的特异性;这只是一个小问题。这意味着它很容易测试和推理

这是一个不使用React的测试线束:

函数wrapHello(组件类){
返回类包装扩展了componentClass{
在handleclick()之前{
log(“我先运行!”)
}
handleClick(…args){
这个。beforeHandleClick()
super.handleClick(…args)
}
}
}
同学们打招呼{
handleClick(){
console.log(“handleClick”)
}
}
const WrappedHello=wrapHello(说你好)
new WrappedHello().handleClick()是一个函数,它接受一个组件参数并返回一个新组件

此函数返回具有修饰的
handleClick
方法的组件:

// A higher-order component that runs some code before
// the given component's `handleClick` method
function wrapHello(componentClass) {
  return class wrapped extends componentClass {
    beforeHandleClick() {
      console.log("I run first!")
    }

    handleClick(...args) {
      this.beforeHandleClick()
      super.handleClick(...args)
    }
  }
}
是整洁的,因为它根本没有反应的特异性;这只是一个小问题。这意味着它很容易测试和推理

这是一个不使用React的测试线束:

函数wrapHello(组件类){
返回类包装扩展了componentClass{
在handleclick()之前{
log(“我先运行!”)
}
handleClick(…args){
这个。beforeHandleClick()
super.handleClick(…args)
}
}
}
同学们打招呼{
handleClick(){
console.log(“handleClick”)
}
}
const WrappedHello=wrapHello(说你好)

新的WrappedHello().handleClick()
您需要类似于动态的东西

这个高阶组件接受一个组件类和一个decorator方法的对象

HOC包装每个具有匹配装饰器的方法。这些方法调用decorator,然后调用原始组件方法。非修饰方法不变

//高阶组件
函数decorateMethods(组件类、decorators){
类decoratedClass扩展componentClass{}
Object.key(decorators).forEach(decoratorName=>{
decoratedClass.prototype[decoratorName]=函数(…args){
decorators[decoratorName]。调用(this,…args);
返回componentClass.prototype[decoratorName]。调用(this,…args)
}
})
返回装饰类
}
//
//试验
//
类组件{
foo(){
console.log(“foo”)
}
bar(){
控制台日志(“bar”)
}
baz(){
控制台日志(“baz”)
}
}
const DecoratedComponent=decoratedMethods(组件{
foo(){
console.log(“在foo之前”)
},
bar(){
console.log(“条前”)
}
})
const d=新装饰组件()
d、 foo()
d、 bar()

d、 baz()
您需要类似于动态的东西

这个高阶组件接受一个组件类和一个decorator方法的对象

HOC包装每个具有匹配装饰器的方法。这些方法调用decorator,然后调用原始组件方法。非修饰方法不变

//高阶组件
函数decorateMethods(组件类、decorators){
类decoratedClass扩展componentClass{}
Object.key(decorators).forEach(decoratorName=>{
decoratedClass.prototype[decoratorName]=函数(…args){
decorators[decoratorName]。调用(this,…args);
返回componentClass.prototype[decoratorName]。调用(this,…args)
}
})
返回装饰类
}
//
//试验
//
类组件{
foo(){
console.log(“foo”)
}
bar(){
控制台日志(“bar”)
}
baz(){
控制台日志(“baz”)
}
}
const DecoratedComponent=decoratedMethods(组件{
foo(){
console.log(“在foo之前”)
},
bar(){
console.log(“条前”)
}
})
const d=新装饰组件()
d、 foo()
d、 bar()

d、 baz()
感谢这个例子——我也能想到类似的东西。我所面临的困难是,我想让包装的组件在知道哪些方法来装饰方面具有动态性。我将在我的原始问题中提供更多的上下文。感谢这个例子-我也能想出类似的东西。我所面临的困难是,我想让包装的组件在知道哪些方法来装饰方面具有动态性。我将在我的原始问题中提供更多的上下文。自定义的“组件前方法”代码也是动态的吗?是的,我希望它只是镜像SayHello组件中的方法。因此,如果我试图覆盖SayHello的handleOnClick,那么它将在handleOnClick之前,如果它是SayHello的handleSomethingElse,那么它将在handleSomethingElse之前。好的,我添加了另一个答案。我离开了第一个,因为我认为它会帮助其他人。自定义的“组件前方法”代码也是动态的吗?是的,我希望它只是镜像SayHello组件中的方法。所以,如果我试图覆盖SayHello的handleOnClick,那么它应该在handleOnClick之前,如果它是