2017-07-02 69 views
1

我對構建可重用的<Element> React組件感興趣。目的是讓任何人使用它來選擇指定一個tagName prop,該prop指示組件將編譯的確切HTML元素。既然這樣,這裏是Element組件的樣子:如何動態生成基於prop的標籤名稱的元素?

import React, { Component } from 'react';  

class Element extends Component { 
    constructor(props) { 
    super(props); 
    this.mapToElement = new Map([ 
     ['ARTICLE', (props, children) => (<article {...props}>{children}</article>)], 
     ['ASIDE', (props, children) => (<aside {...props}>{children}</aside>)], 
     ['DIV', (props, children) => (<div {...props}>{children}</div>)], 
     ['FOOTER', (props, children) => (<footer {...props}>{children}</footer>)], 
     ['HEADER', (props, children) => (<header {...props}>{children}</header>)], 
     ['MAIN', (props, children) => (<main {...props}>{children}</main>)], 
     ['P', (props, children) => (<p {...props}>{children}</p>)], 
     ['SECTION', (props, children) => (<section {...props}>{children}</section>)], 
     ['SPAN', (props, children) => (<span {...props}>{children}</span>)] 
    ]); 
    } 

    render() { 
    const { 
     children, 
     tagName = 'DIV', 
     ...rest 
    } = this.props; 

    return (this.mapToElement.get(tagName.toUpperCase())(rest, children)); 
    } 
}; 

可以看出,但是,此組件的能力,成功的工作是由HTML tagNames到其對應的JSX語法相當冗長的映射驅動。我最好喜歡讓這個組件支持所有非自閉HTML元素,但顯然希望這樣做,而不必強制擴展此映射以包含符合該標準的每個可能的HTML元素。

有沒有一種更具動態性,面向未來的方式來做到這一點,如果是的話,那會是什麼樣子?

回答

1

如果我理解正確的話,你只是創建React.createElement一個包裝物,什麼都JSX是transpiled到創建你的元素:

render() { 
    const { 
    children, 
    tagName = 'div', 
    ...rest 
    } = this.props; 

    return React.createElement(tagName, rest, children); 
} 

這樣:

<Element tagName="span" foo="bar"> 
    Foobar! 
</Element> 

將成爲(一旦transpiled):

React.createElement('span', { 
    foo: 'bar' 
}, 'Foobar!'); 

哪個是一樣的:

<span foo="bar">Foobar!</span> 

如果你永遠只能要限制它只是DOM元素,而不是定製的反應的組分,只是限制proptype或驗證自己的類型:

tagName: PropType.string.isRequired 

,或者你自己的驗證:

tagName: (props, propName, componentName) => { 
    if(typeof props[propName] !== 'string') { 
    return new Error(`The ${propName} prop should be a string in ${componentName}`); 
    } 
} 
+0

jeeeezz ...我覺得很愚蠢。我已經習慣了ES6風格的React代碼,我完全忘記了'createElement'方法對我們仍然可用。你百分百滿足我所尋找的東西。謝謝@AndrewLi – IsenrichO

+0

@IsenrichO沒問題,它發生在我們身上。乾杯! – Li357

+0

在這種情況下,我更傾向於使用自定義驗證器。這似乎是警告自閉HTML標籤的最佳地點。儘管我仍然沒有看到一種更有效的方式,即不是基於檢查這些禁止標籤列表的驗證工作。例如,'if(['BR','HR','IMAGE','INPUT','META','SOURCE','TRACK','WBR']包括(propName.toUpperCase())){ //拋出錯誤}' – IsenrichO