Подтвердить что ты не робот

Как условно обернуть компонент React?

У меня есть компонент, который иногда нужно визуализировать как <anchor>, а иногда как <div>. prop, который я прочитал, чтобы определить это, - this.props.url.

Если он существует, мне нужно сделать компонент, завернутый в <a href={this.props.url}>. В противном случае он просто отображается как <div/>.

Возможно ли это?

Это то, что я делаю сейчас, но чувствую, что это можно упростить:

if (this.props.link) {
    return (
        <a href={this.props.link}>
            <i>
                {this.props.count}
            </i>
        </a>
    );
}

return (
    <i className={styles.Icon}>
        {this.props.count}
    </i>
);

UPDATE:

Вот заключительная блокировка. Спасибо за совет, @Sulthan!

import React, { Component, PropTypes } from 'react';
import classNames from 'classnames';

export default class CommentCount extends Component {

    static propTypes = {
        count: PropTypes.number.isRequired,
        link: PropTypes.string,
        className: PropTypes.string
    }

    render() {
        const styles = require('./CommentCount.css');
        const {link, className, count} = this.props;

        const iconClasses = classNames({
            [styles.Icon]: true,
            [className]: !link && className
        });

        const Icon = (
            <i className={iconClasses}>
                {count}
            </i>
        );

        if (link) {
            const baseClasses = classNames({
                [styles.Base]: true,
                [className]: className
            });

            return (
                <a href={link} className={baseClasses}>
                    {Icon}
                </a>
            );
        }

        return Icon;
    }
}
4b9b3361

Ответ 1

Просто используйте переменную.

var component = (
    <i className={styles.Icon}>
       {this.props.count}
    </i>
);

if (this.props.link) {
    return (
        <a href={this.props.link} className={baseClasses}>
            {component}
        </a>
    );
}

return component;

или вы можете использовать вспомогательную функцию для визуализации содержимого. JSX - это код, как и любой другой. Если вы хотите уменьшить дублирование, используйте функции и переменные.

Ответ 2

Создайте HOC (компонент более высокого порядка) для упаковки вашего элемента:

const WithLink = ({ link, className, children }) => (link ?
  <a href={link} className={className}>
    {children}
  </a>
  : children
);

return (
  <WithLink link={this.props.link} className={baseClasses}>
    <i className={styles.Icon}>
      {this.props.count}
    </i>
  </WithLink>
);

Ответ 3

Вот пример полезного компонента, который я видел, использовал (не уверен, кто его аккредитовал), который делает эту работу:

const ConditionalWrap = ({ condition, wrap, children }) => (
 condition ? wrap(children) : children
);

Случай использования:


<ConditionalWrap
  condition={Boolean(someCondition)}
  wrap={children => (<a>{children}</a>)} // Can be anything
>
 This text is passed as the children arg to the wrap prop
</ConditionalWrap>


Ответ 4

Вы также можете использовать этот компонент: условная упаковка

Простой компонент React для переноса дочерних элементов на основе условия.

Ответ 5

Вы должны использовать JSX if-else, как описано здесь. Что-то вроде этого должно работать.

App = React.creatClass({
    render() {
        var myComponent;
        if(typeof(this.props.url) != 'undefined') {
            myComponent = <myLink url=this.props.url>;
        }
        else {
            myComponent = <myDiv>;
        }
        return (
            <div>
                {myComponent}
            </div>
        )
    }
});

Ответ 6

Вы также можете использовать функцию утилит, как это:

const wrapIf = (conditions, content, wrapper) => conditions
        ? React.cloneElement(wrapper, {}, content)
        : content;

Ответ 7

Там другой способ Вы можете использовать ссылочную переменную

let Wrapper = React.Fragment //fallback in case you dont want to wrap your components

if(someCondition) {
    Wrapper = ParentComponent
}

return (
    <Wrapper parentProps={parentProps}>
        <Child></Child>
    </Wrapper>

)