我如何有条件地包装React组件?

Bra*_*ham 66 javascript reactjs

我有一个组件,有时需要作为一个锚呈现,其他时候作为一个简单的div.在<anchor>我触发关断的,以确定所需要的是<div>道具.如果它存在,我需要渲染包含在锚点中的组件prop.否则它只是呈现为this.props.url.

可能?

这就是我现在正在做的事情,但感觉它可以简化:

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>
);
Run Code Online (Sandbox Code Playgroud)

更新:

这是最后的锁定.谢谢你的提示,@ 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

Sul*_*han 79

只需使用变量.

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;
Run Code Online (Sandbox Code Playgroud)

或者,您可以使用辅助函数来呈现内容.JSX就像其他任何代码一样.如果要减少重复,请使用函数和变量.


Do *_*ync 16

创建一个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>
);
Run Code Online (Sandbox Code Playgroud)

  • HOC 应该慢慢消亡:P (7认同)
  • 这不是 HOC。来自 [React 文档](https://reactjs.org/docs/higher-order-components.html):“具体来说,高阶组件是一个接受一个组件并返回一个新组件的函数。” 这里,“WithLink”只是一个组件。这个例子看起来好像它是在另一个组件中声明的,这几乎总是一个坏主意,因为它将在每次渲染时重新创建,这意味着子组件将不断重新安装。 (7认同)

Avi*_*ash 15

还有另一种方法可以使用引用变量

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>

)
Run Code Online (Sandbox Code Playgroud)

  • 您可以将前半部分压缩为 `let Wrapper = someCondition ?父组件:React.Fragment` (3认同)

ant*_*ony 9

这是我看过用来完成工作的有用组件的一个示例(不确定谁授权它):

const ConditionalWrap = ({ condition, wrap, children }) => (
 condition ? wrap(children) : children
);
Run Code Online (Sandbox Code Playgroud)

用例:


<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>


Run Code Online (Sandbox Code Playgroud)

  • 信用可能应该放在这里:https://gist.github.com/kitze/23d82bb9eb0baabfd03a6a720b1d637f (3认同)

小智 8

const ConditionalWrapper = ({ condition, wrapper, children }) => 
  condition ? wrapper(children) : children;
Run Code Online (Sandbox Code Playgroud)

您想要包装的组件

<ConditionalWrapper
   condition={link}
   wrapper={children => <a href={link}>{children}</a>}>
   <h2>{brand}</h2>
</ConditionalWrapper>
Run Code Online (Sandbox Code Playgroud)

也许这篇文章可以帮助你更多 https://blog.hackages.io/conditionally-wrap-an-element-in-react-a8b9a47fab2