【发布时间】:2021-05-17 18:38:52
【问题描述】:
我会用一个例子来最好地解释我想说的: 我想创建一个可以重复使用的可悬停组件。 如果我只使用扩展,代码将如下所示:
继承:
class HoverableComponent extends React.Component {
constructor(props){
super(props);
this.state = {hover: false}
}
protected abstract customRender();
render(){
return <div
onMouseOver={() => this.setState({hover: true})}
onMouseOut={() => this.setState({hover: false})}
>
{this.customRender()}
</div>
}
}
class MyClass extends HoverableComponent {
customRender(){
return ... // do stuff with this.state.hover
}
}
这样做的缺点是我必须使用customRender 函数来渲染组件。
作曲:
class HoverableComponent extends React.Component {
render(){
return <div
onMouseOver={() => this.props.onHoverChange(true))}
onMouseOut={() => this.props.onHoverChange(false))}
>
{this.props.children}
</div>
}
}
class MyClass extends React.Component {
constructor(props){
super(props);
this.state = {hover: false}
}
handleHoverChange = (hover) => this.setState({hover: hover});
render(){
return <HoverableComponent
onHoverChange={this.handleHoverChange}
>
... JSX ....
</HoverableComponent
}
}
这种方法的缺点是我必须在父组件中创建一个状态变量,但我会以一种反应灵敏的方式进行渲染
所以我在想我是否可以同时使用这两种方法来获得我想要的东西,否则最终会变成一个非常混乱的代码。
两者
class HoverableComponent extends React.Component {
constructor(props){
super(props);
this.state = {hover: false}
}
render(){
return <div
onMouseOver={() => this.setState({hover: true})}
onMouseOut={() => this.setState({hover: false})}
>
{this.props.children}
</div>
}
}
class MyClass extends HoverableComponent {
render(){
return <HoverableComponent>
// do stuff with this.state.hover
</HoverableComponent>
}
}
对于这种情况,这三种方法中的哪一种被认为是最佳实践?还有其他我应该使用的方法吗?我想把它扩大到还有例如DraggableComponent、ClickableComponent等。
【问题讨论】:
标签: reactjs inheritance design-patterns composition class-extensions