是否可以为React组件实现类似继承的机制,以减少几乎重复的代码?

问题描述

我发现我不得不重新实现许多相同的功能。例如,对于接下来的3个组件,我将为styleclassNameid实现相同的代码。我知道可以将{...props}作为参数来代替,然后再将{...props}传递给return函数中的容器,但是如果我希望这些组件各有其作用,则无法执行此操作自己的className和样式始终分配给这些类的每个实例。我稍微看了一下higher-order-components,但无法理解在这种情况下如何使用它们

const styles = {
    container:{
        position: 'absolute'
    },}

const Modal = ({className,style,id,hidden,children}) => {

    return (
        <div 
            className={`modal ${className}`}
            style={...{styles.container},...{style}}
            id={id}
        >
            {!hidden && <ExtraContent />}
            {children}
        </div>
    )
}

const styles = {
    container:{
        margin: 10
    }
}

const VoteButton = ({className,pressed}) => {
    let img
    if (pressed){
        img = './img_pressed.jpg'
    }else{
        img = './img_not_pressed.jpg'
    }
    return (
        <div
            className={`VoteButton ${className}`}
            style={...{styles.container},...{style}}
            id={id}
        >
            <img src={img}>
        </div>
    )
}

const styles = {
    container:{
        display: 'flex'
    }
}

const Navbar = ({className,links,children,...props}) => {
    return (
        <nav 
            {...props}
            className={`navbar ${className}`}
            style={...{styles.container},...{style}}
            id={id}
        >
            {links.map(lk => <a href={lk.href}>{lk.text}</a>
            {children}
        </nav>
    )
}

为了清楚起见,我正在寻找一种避免为每个组件定义和修改classNamestyleid方法。如果我能做一次会很好。我了解这对于第三个组件可能尤其困难,因为它是nav而不是div。

解决方法

一种方法是拥有一个返回您的组件函数的函数:

function createComponentClass(Ele,name,styles,children) {
  return (props) => {
    const { className,style,id } = props;
    return (
      <Ele className={`${name} ${className}`} style={...{styles.container},...{style}} id={id}>
        {children(props)}
      </Ele>
    );
  };
}

const Modal = createComponentClass('div','modal',{ container: { ... } },(props) => {
  return (
    <>
      {!props.hidden && <ExtraContent />}
      {props.children}
    </>
  );
});

const VoteButton = createComponentClass('div','voteButton',(props) => {
  let img = pressed ? './img_pressed.jpg' : './img_not_pressed.jpg';
  return <img src={img} />;
});

const Navbar = createComponentClass('nav','navbar',(props) => {
  return (
    <>
      {links.map(lk => <a href={lk.href}>{lk.text}</a>
      {children}
    </>
  );
});

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...