Я обнаружил, что мне приходится заново реализовывать многие из тех же функций. Например, со следующими тремя компонентами я реализую один и тот же код для style, className и id. Я знаю, что могу использовать {...props} в качестве аргумента вместо того, чтобы слышать, а затем передать {...props} в контейнер внутри функции возврата, но я не могу сделать это, если хочу, чтобы каждый из этих компонентов имел свои собственные имена классов и стили, которые всегда назначаются каждому экземпляру этих классов. Я немного просмотрел компоненты более высокого порядка, но не смог обернуть моя голова вокруг, как я бы использовал их в этом случае

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, style, id, 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, style, id, 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>
    )
}

Чтобы было ясно, я ищу способ избежать необходимости определять и изменять className, style и id для каждого компонента. Было бы хорошо, если бы я смог сделать это один раз. Я понимаю, что это может быть особенно сложно для третьего компонента, учитывая, что это nav вместо div.

1
Sam 7 Окт 2020 в 22:59

1 ответ

Лучший ответ

Один из подходов - иметь функцию, которая возвращает функцию вашего компонента:

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', { container: { ... } }, (props) => {
  let img = pressed ? './img_pressed.jpg' : './img_not_pressed.jpg';
  return <img src={img} />;
});

const Navbar = createComponentClass('nav', 'navbar', { container: { ... } }, (props) => {
  return (
    <>
      {links.map(lk => <a href={lk.href}>{lk.text}</a>
      {children}
    </>
  );
});
2
Wex 7 Окт 2020 в 20:39