本文轉載自:衆成翻譯
譯者:iOSDevLog
連接:http://www.zcfy.cc/article/3819
原文:https://www.fullstackreact.com/30-days-of-react/day-11/react
React提供了幾種建立組件的不一樣方法。今天咱們將討論建立組件的最終方案,即無狀態函數的純組件。app
咱們已經研究了幾種不一樣的方法來構建反應組件。 經過這一點咱們遺漏的一種方法是構建React組件的無狀態組件/功能方法。框架
正如咱們已經看到的那樣,咱們只使用React.Component
和React.createClass()
方法構建組件。 爲了得到更多的性能和簡單性,React _一樣_容許咱們使用正常的JavaScript函數建立純粹的,無狀態的組件。函數
純組件能夠替換隻有 render
功能的組件。 而不是使一個完整的組件只是將一些內容呈現到屏幕,咱們能夠建立一個_純_一個代替。工具
_純_組件是咱們能夠編寫的最簡單,最快的組件。 它們易於編寫,簡單易用,以及咱們能夠撰寫的最快的組件。 在咱們深刻_爲何_以前,這些更好,讓咱們寫一個,或者一對!性能
// The simplest one const HelloWorld = () => (<div>Hello world</div>); // A Notification component const Notification = (props) => { const {level, message} = props; const classNames = ['alert', 'alert-' + level] return ( <div className={classNames}> {message} </div> ) }; // In ES5 var ListItem = function(props) { var handleClick = function(event) { props.onClick(event); }; return ( <div className="list"> <a href="#" onClick={handleClick}> {props.children} </a> </div> ) }
因此他們只是功能,對吧?是的! 因爲它們只是函數,因此使用純JavaScript進行測試很是簡單。 這個想法是,若是React知道發送到組件中的 props
,知道是否必須從新投遞,這多是肯定性的。 相同的屬性在相同的輸出虛擬DOM中。測試
在React中,功能組件被稱爲一個參數 的props
(相似於 React.Component
構造函數類),它們是它所調用的 props
,以及組件樹的當前context
。this
例如,假設咱們想使用功能組件來重寫咱們原來的 Timer
組件,由於咱們但願給用戶一個動態的方式來設置本身的時鐘風格(24 / 12小時時鐘使用不一樣的分隔符,也許他們不想顯示秒數等)。spa
咱們能夠將咱們的時鐘分解成多個組件,咱們能夠將每一個時間段用做單個組件。 咱們可能像這樣打破他們:翻譯
const Hour = (props) => { let {hours} = props; if (hours === 0) { hours = 12; } if (props.twelveHours) { hours -= 12; } return (<span>{hours}</span>) }
const Minute = ({minutes}) => (<span>{minutes<10 && '0'}{minutes}</span>)
const Second = ({seconds}) => (<span>{seconds<10 && '0'}{seconds}</span>)
const Separator = ({separator}) => (<span>{separator || ':'}</span>)
const Ampm = ({hours}) => (<span>{hours >= 12 ? 'pm' : 'am'}</span>)
經過這些,咱們能夠經過他們是完整的React組件(它們是)放置單個組件:
<div>Minute: <Minute minutes={12} /></div> <div>Second: <Second seconds={51} /></div>
咱們能夠重構咱們的時鐘組件來接受 format
字符串,並分解這個字符串,只選擇用戶感興趣的組件。 有多種方法能夠解決這個問題,好比強制邏輯進入Clock
組件_或者_咱們能夠建立另外一個接受格式字符串的無狀態組件。 讓咱們這樣作(更容易測試):
const Formatter = (props) => { let children = props.format.split('').map((e, idx) => { if (e === 'h') { return <Hour key={idx} {...props} /> } else if (e === 'm') { return <Minute key={idx} {...props} /> } else if (e === 's') { return <Second key={idx} {...props} /> } else if (e === 'p') { return <Ampm key={idx} {...props} /> } else if (e === ' ') { return <span key={idx}> </span>; } else { return <Separator key={idx} {...props} /> } }); return <span>{children}</span>; }
這是一個有點醜陋的key
和 {...props}
的東西。 React爲咱們提供了一些幫助映射children的屬性,而且經過React.Children
對象來處理每一個孩子的惟一key
。
Clock 組件的
render() 函數能夠大大簡化,這要歸功於
Formatter` 組件:
class Clock extends React.Component { state = { currentTime: new Date() } componentDidMount() { this.setState({ currentTime: new Date() }, this.updateTime); } componentWillUnmount() { if (this.timerId) { clearTimeout(this.timerId) } } updateTime = e => { this.timerId = setTimeout(() => { this.setState({ currentTime: new Date() }, this.updateTime); }) } render() { const { currentTime } = this.state const hour = currentTime.getHours(); const minute = currentTime.getMinutes(); const second = currentTime.getSeconds(); return ( <div className='clock'> <Formatter {...this.props} state={this.state} hours={hour} minutes={minute} seconds={second} /> </div> ) } }
咱們的 Clock
組件不只更簡單,並且更容易測試。 它_也_將幫助咱們過渡到使用數據狀態樹,如Flux / Redux框架,但更多的是在之後。
在React中使用功能組件的優勢是:
this
關鍵字(即不須要綁定)你可能會說爲何不使用功能組件?那麼使用功能組件的一些缺點就會有一些優勢:
this
關鍵字總的來講,喜歡嘗試在其較重的 React.Component
表兄弟中使用功能組件是一個很好的主意。當咱們討論React中的數據管理時,咱們將看到咱們如何使用這些演示組件與數據做爲純粹的props
。
今天工做得不錯,咱們已經成功實現了React等級。咱們如今知道製做React組件的_三種_方法。明天,咱們將使用React團隊開發的軟件包管理工具,使用/構建React應用程序進行設置: create-react-app
。