我们说我有以下React Component类:
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");
}
}
我想要做的是创建一个更高阶的组件,该组件知道handleOnClick
中的SayHello
,但之前调用SayHello
&#39; s { {1}},我希望它能够执行我先传入的一些代码(即我想运行在我的服务器中记录某些内容的代码)。
是否有React模式可以做这样的事情?
修改
我想在这里提供更多背景信息。我希望我的高阶组件在调用哪些方法时是动态的。例如,有时它可能是handleOnClick
,但有时可能是handleOnClick
。
答案 0 :(得分:5)
higher-order component是一个接受组件参数并返回新组件的函数。
此函数返回一个带有装饰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)
}
}
}
This pattern很整洁,因为它根本不属于React;它只是pure function。这意味着它易于测试和推理。
这是一个没有使用React的测试工具:
function wrapHello(componentClass) {
return class wrapped extends componentClass {
beforeHandleClick() {
console.log("I run first!")
}
handleClick(...args) {
this.beforeHandleClick()
super.handleClick(...args)
}
}
}
class SayHello {
handleClick() {
console.log("handleClick")
}
}
const WrappedHello = wrapHello(SayHello)
new WrappedHello().handleClick()
&#13;
答案 1 :(得分:2)
你需要像动态mixin这样的东西。
这个高阶组件采用Component类和装饰器方法的对象。
HOC包装每个具有匹配装饰器的方法。这些方法调用装饰器然后调用原始组件方法。非装饰方法不变。
str.split(" ").toList.map { s =>
if(replacements.get(s).isDefined) {
replacements(s)
} else {
s
}
}.mkString(" ")
在这种情况下,装饰器方法与基类方法名称完全匹配。如果你想要装饰器使用,例如相反,// Higher-order component
function decorateMethods(componentClass, decorators) {
class decoratedClass extends componentClass { }
Object.keys(decorators).forEach(decoratorName => {
decoratedClass.prototype[decoratorName] = function(...args) {
decorators[decoratorName].call(this, ...args);
return componentClass.prototype[decoratorName].call(this, ...args)
}
})
return decoratedClass
}
//
// Test
//
class Component {
foo() {
console.log("foo")
}
bar() {
console.log("bar")
}
baz() {
console.log("baz")
}
}
const DecoratedComponent = decorateMethods(Component, {
foo() {
console.log("before foo")
},
bar() {
console.log("before bar")
}
})
const d = new DecoratedComponent()
d.foo()
d.bar()
d.baz()
可以使用以下方法映射方法名称:
beforeFoo