У меня есть компонент, который иногда нужно отображать как файл, <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>
);
ОБНОВИТЬ:
Вот и последний тупик. Спасибо за подсказку, @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;
}
}
javascript
reactjs
Брэндон Дарем
источник
источник
const baseClasses =
в этуif (this.props.link)
ветку. Поскольку вы используете ES6, вы также можете немного упростить,const {link, className} = this.props;
а затем использоватьlink
и вclassName
качестве локальных переменных.Ответы:
Просто используйте переменную.
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 - это такой же код, как и любой другой. Если вы хотите уменьшить дублирование, используйте функции и переменные.
источник
Создайте 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> );
источник
HOC
ужасный. Это просто функция, которая находится посередине. Я действительно вытесняю это внезапно модное название «HPC». что такого важного в простой функции, которая находится между ... старой концепцией на протяжении десятилетий.Вот пример полезного компонента, который я использовал (не уверен, на кого его аккредитовать), который выполняет эту работу:
const ConditionalWrap = ({ condition, wrap, children }) => ( condition ? wrap(children) : children );
Пример использования:
<ConditionalWrap condition={someCondition} wrap={children => (<a>{children}</a>)} // Can be anything > This text is passed as the children arg to the wrap prop </ConditionalWrap>
источник
wrap
декларативно, а не как функцию, чтобы вещи были более "React" -spiritЕсть еще один способ использовать ссылочную переменную
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> )
источник
let Wrapper = someCondition ? ParentComponent : React.Fragment
React.Fragment can only have 'key' and 'children'
потому что передаю некоторые реквизиты в «<Wrapper>», например, «className» и такВы также можете использовать такую служебную функцию:
const wrapIf = (conditions, content, wrapper) => conditions ? React.cloneElement(wrapper, {}, content) : content;
источник
const ConditionalWrapper = ({ condition, wrapper, children }) => condition ? wrapper(children) : children;
Компонент, который вы хотите обернуть
<ConditionalWrapper condition={link} wrapper={children => <a href={link}>{children}</a>}> <h2>{brand}</h2> </ConditionalWrapper>
Возможно, эта статья поможет вам больше https://blog.hackages.io/conditional-wrap-an-element-in-react-a8b9a47fab2
источник
Вы должны использовать 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> ) } });
источник
Функциональный компонент, который визуализирует 2 компонента: один в оболочке, а другой нет.
Способ 1:
// The interesting part: const WrapIf = ({ condition, With, children, ...rest }) => condition ? <With {...rest}>{children}</With> : children const Wrapper = ({children, ...rest}) => <h1 {...rest}>{children}</h1> // demo app: with & without a wrapper const App = () => [ <WrapIf condition={true} With={Wrapper} style={{color:"red"}}> foo </WrapIf> , <WrapIf condition={false} With={Wrapper}> bar </WrapIf> ] ReactDOM.render(<App/>, document.body)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
Это также можно использовать так:
<WrapIf condition={true} With={"h1"}>
Способ 2:
// The interesting part: const Wrapper = ({ condition, children, ...props }) => condition ? <h1 {...props}>{children}</h1> : <React.Fragment>{children}</React.Fragment>; // stackoverflow prevents using <></> // demo app: with & without a wrapper const App = () => [ <Wrapper condition={true} style={{color:"red"}}> foo </Wrapper> , <Wrapper condition={false}> bar </Wrapper> ] ReactDOM.render(<App/>, document.body)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
источник