React:高阶组件渲染有更好的模式吗?

时间:2016-06-23 19:14:02

标签: javascript reactjs functional-programming

这是一个实际的例子。

className

现在,每个组件呈现的实际HTML因元素和<h1 className="pageHeading">{props.text}</h1> <h2 className="modalHeading">{props.text}</h2> 而异。

sub

等。使用sectionpropTypes

现在,在classNames,元素和import React from 'react'; require('./Icon.css'); const editGlyph = <path d="M5 14l-3-3 8-8 3 3zM11 2l2-2 3 3-2 2zM0 16l3-1-2-2" />; const backGlyph = <path d="M2 7.994L8.137 16h4.312L6.31 7.994 12.45 0H8.136" />; const addGlyph = <path d="M9.008 7.132V1H7.104v6.132H1v1.904h6.104v6.132h1.904V9.036h6.104V7.132" />; const requiredGlyph = <path d="M4.79 3.42V1H3.655v2.42l-2.27-.857L1 3.59l2.27.815-1.392 1.95.964.662 1.392-2.055L5.71 7.017l.88-.663-1.414-1.95 2.334-.813-.428-1.027" /> const informationGlyph = <g transform="translate(0 .61)"><path d="M6.857 5.143h-2.57V6h.856v2.57h-.857v.86h3.428v-.86h-.857" /><ellipse cx="6" cy="3.429" rx=".857" ry=".857" /><path d="M6 0C2.687 0 0 2.687 0 6s2.687 6 6 6 6-2.687 6-6-2.687-6-6-6zm0 11.143C3.164 11.143.857 8.836.857 6S3.164.857 6 .857 11.143 3.164 11.143 6 8.836 11.143 6 11.143z" /></g>; let iconGlyph; export default function Icon(props) { switch (props.glyph) { case 'add': iconGlyph = addGlyph; break; case 'back': iconGlyph = backGlyph; break; case 'edit': iconGlyph = editGlyph; break; case 'required': iconGlyph = requiredGlyph; break; case 'i': iconGlyph = informationGlyph; break; default: iconGlyph = null; break; } return ( <svg id="icon" className={[`icon ${props.className}`]} viewBox="0 0 16 16" aria-labelledby="title" > <title id={props.title}>{props.title}</title> {iconGlyph} </svg> ) } Icon.propTypes = { glyph: React.PropTypes.oneOf(['add', 'back', 'edit', 'i', 'required']).isRequired, className: React.PropTypes.string, title: React.PropTypes.string, } 之间,有没有更好的方法来选择要呈现的内容并使它们保持同步而不使用switch语句?

作为另一种选择,但类似的例子,我在这里用Icon类做了这个。

    string imageUrl = "http://imageurl.com/image.png"
    HtmlNode imageNode = HtmlNode.CreateNode("<img src=\"" + imageUrl");

    string htmlEmail = mailItem.HTMLBody
    HtmlAgilityPack.HtmlDocument html = new HtmlAgilityPack.HtmlDocument();
            html.LoadHtml(htmlEmail);
    HtmlNode body = html.DocumentNode.SelectSingleNode("//body");
    body.AppendChild(imageNode);
    html.DocumentNode.WriteTo();

我不知道它是什么,但我不能感觉有一种更优雅的方式来处理这个问题。也许装饰师有一些参数?

1 个答案:

答案 0 :(得分:3)

如果我正确理解您的问题,您可以执行以下操作。 Demo

const { oneOf, string } = PropTypes

// save all your options in hash
const icons = {
  edit: <path d="M5 14l-3-3 8-8 3 3zM11 2l2-2 3 3-2 2zM0 16l3-1-2-2" />,
  back: <path d="M2 7.994L8.137 16h4.312L6.31 7.994 12.45 0H8.136" />,
  add: <path d="M9.008 7.132V1H7.104v6.132H1v1.904h6.104v6.132h1.904V9.036h6.104V7.132" />,
  required: <path d="M4.79 3.42V1H3.655v2.42l-2.27-.857L1 3.59l2.27.815-1.392 1.95.964.662 1.392-2.055L5.71 7.017l.88-.663-1.414-1.95 2.334-.813-.428-1.027" />,
  i: <g transform="translate(0 .61)"><path d="M6.857 5.143h-2.57V6h.856v2.57h-.857v.86h3.428v-.86h-.857" /><ellipse cx="6" cy="3.429" rx=".857" ry=".857" /><path d="M6 0C2.687 0 0 2.687 0 6s2.687 6 6 6 6-2.687 6-6-2.687-6-6-6zm0 11.143C3.164 11.143.857 8.836.857 6S3.164.857 6 .857 11.143 3.164 11.143 6 8.836 11.143 6 11.143z" /></g>
}

// Icon is stateless
const Icon = ({ type, className, title }) => (
    <svg
      id="icon"
      className={[`icon ${className}`]}
      viewBox="0 0 16 16"
      aria-labelledby="title"
    >
      <title id={title}>{title}</title>
      {/* Assuming type is the same as key in icons */}
      {icons[type] || null}
    </svg>
)

Icon.propTypes = {
  // make this constain "dynamic"
  glyph: oneOf(Object.keys(icons)).isRequired,
  className: string,
  title: string,
}