首页 > 解决方案 > 在 React 类组件中同时使用继承和组合是一种好的做法吗?

问题描述

我会用一个例子来最好地解释我想说的:我想创建一个可以重复使用的可悬停组件。如果我只使用扩展,代码将如下所示:

继承

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等等。

标签: reactjsinheritancedesign-patternscompositionclass-extensions

解决方案


React 建议尽可能使用组合而不是继承,并且仅应在非常特定的情况下使用继承。

https://www.tutorialspoint.com/composition-vs-inheritance-in-react-js#:~:text=Composition%20and%20inheritance%20are%20the,in%20very%20specific%20cases%20only

为了防止重复多次,为什么不将可重用方法实现为自定义钩子。您可以一次定义所有需要的方法,然后在任何需要的地方使用它们。

const [handleHoverChange]= useHoverableComponent();

推荐阅读