Как условно обернуть компонент 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;
}
}
Ответы
Ответ 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>
)