在我阅读了mixins有多糟糕并且自己做了一些不好的经历之后,我想重构我的代码以使用mixin来实现可重用性。
我想要一个组件来发出事件并且可以设置样式。所以我有mixins EventEmitter,它包含操作事件的函数和包含操作样式的函数的Stylable。
var Styleable = {
addStyleProperty: function(styleProperty) {
...
},
...
};
var EventEmitter = {
addEventListener: function(eventName, func) {
},
...
};
使用mixins,示例组件如下所示:
var Button = React.createClass({
mixins = [EventEmitter, Styleable],
...
});
使用合成我尝试为Styleable和EventEmitter创建组件,如下所示:
var StylableComponent = React.createClass({
addStyleProperty: ...
render: function() {
React.createElement(this.props.wrappedComponent, ...)??
}
}
var EventEmitterComponent = ...
但我不知道如何正确使用它们。我读到我必须使用这些组件作为包装器,但我不知道如何实现这一点。我试着像上面例子的渲染函数那样做。如何实现具有与mixin变体类似的功能的按钮?所以我只是传递了所需的功能:
<Button is={[StyleableComponent, EventEmitterComponent]}/>
或者我期待作曲的错误行为?
答案 0 :(得分:1)
基本上,您希望创建一个返回全新组件的函数。
例如,对于您的EventEmitter,它看起来像这样:
import eventEmitter from 'your-event-emitter-location';
// This function takes a component as an argument, and returns a component.
function eventEmitterWrapper(ComposedComponent) {
// This is the brand new "wrapper" component we're creating:
return class extends Component {
render() {
// We want to return the supplied component, with all of its supplied
// props, but we also want to "add in" our additional behaviour.
return (
<ComposedComponent
{...this.props}
eventEmitter={eventEmitter}
/>
);
}
}
}
要使用它,你可以这样做:
import Button from '../Button';
import eventEmitterWrapper from '../../HOCs/event-emitter';
class Home extends Component {
render() {
const EventEmitterButton = eventEmitterWrapper(Button);
return (
<div>
<EventEmitterButton onClick={doSomething}>
Hello there!
</EventEmitterButton>
</div>
)
}
}
最后,在你的按钮中,你可以从道具中访问事件发射器:
const Button = ({ children, onClick, eventEmitter }) => {
// Let's say, for example, you want to emit an event whenever the
// button is clicked. You could do something like this:
const clickHandler = (ev) => {
onClick(ev);
if (eventEmitter) {
eventEmitter.emit('click', ev);
}
};
return (
<button onClick={clickHandler}>
{children}
<button>
)
}
注意:这是一个人为的例子。这种模式对我来说有点臭; Button
对事件发射器的内部工作方式了解得太多(例如,它不需要知道它有emit
方法。如果你改变了事件发射器的工作方式,你就是' d有一堆“哑”组件要更新。
为了解决这个问题,我需要了解更多关于你的用例的信息,但我可能会让eventEmitterWrapper
函数返回的类暴露出简单的特定方法(例如“emitEvent”,这将采用鼠标/键盘事件的单个参数)
希望它说明了如何使用更高阶的组件!
补充阅读: