【全棧React】第11天: 純組件

本文轉載自:衆成翻譯
譯者:iOSDevLog
連接:http://www.zcfy.cc/article/3819
原文:https://www.fullstackreact.com/30-days-of-react/day-11/react

React提供了幾種建立組件的不一樣方法。今天咱們將討論建立組件的最終方案,即無狀態函數的純組件。app

咱們已經研究了幾種不一樣的方法來構建反應組件。 經過這一點咱們遺漏的一種方法是構建React組件的無狀態組件/功能方法。框架

正如咱們已經看到的那樣,咱們只使用React.ComponentReact.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 ,以及組件樹的當前contextthis

例如,假設咱們想使用功能組件來重寫咱們原來的 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關鍵字(即不須要綁定)
  • 演示組件(也稱爲啞組件)強調UI超越業務邏輯(即組件中沒有狀態操縱)
  • 鼓勵創建較小的,獨立的組件
  • 強調嚴格的代碼(更好重構)
  • 快速,快速,快速(重要的話要說3遍)
  • 他們是_容易_重用

你可能會說爲何不使用功能組件?那麼使用功能組件的一些缺點就會有一些優勢:

  • 沒有生命週期回調鉤子函數
  • 功能有限
  • 沒有this 關鍵字

總的來講,喜歡嘗試在其較重的 React.Component 表兄弟中使用功能組件是一個很好的主意。當咱們討論React中的數據管理時,咱們將看到咱們如何使用這些演示組件與數據做爲純粹的props

今天工做得不錯,咱們已經成功實現了React等級。咱們如今知道製做React組件的_三種_方法。明天,咱們將使用React團隊開發的軟件包管理工具,使用/構建React應用程序進行設置: create-react-app

相關文章
相關標籤/搜索