欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

React 無狀態(tài)組件(Stateless Component) 與高階組件

 更新時(shí)間:2018年08月14日 09:20:59   作者:jacobbubu  
這篇文章主要介紹了React 無狀態(tài)組件(Stateless Component) 與高階組件,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧

無狀態(tài)組件(Stateless Component) 是 React 0.14 之后推出的,大大增強(qiáng)了編寫 React 組件的方便性,也提升了整體的渲染性能。

無狀態(tài)組件 (Stateless Component)

function HelloComponent(props, /* context */) {
 return <div>Hello {props.name}</div>
}
ReactDOM.render(<HelloComponent name="Sebastian" />, mountNode)

HelloComponent 第一個(gè)參數(shù)是 props,第二個(gè)是 context。最后一句也可以這么寫:

ReactDOM.render(HelloComponent{ name:"Sebastian" }, mountNode)

可以看到,原本需要寫“類”定義(React.createClass 或者 class YourComponent extends React.Component)來創(chuàng)建自己組件的定義,現(xiàn)在被精簡成了只寫一個(gè) render 函數(shù)。更值得一提的是,由于僅僅是一個(gè)無狀態(tài)函數(shù),React 在渲染的時(shí)候也省掉了將“組件類” 實(shí)例化的過程。

結(jié)合 ES6 的解構(gòu)賦值,可以讓代碼更精簡。例如下面這個(gè) Input 組件:

function Input({ label, name, value, ...props }, { defaultTheme }) {
 const { theme, autoFocus, ...rootProps } = props
 return (
  <label
   htmlFor={name}
   children={label || defaultLabel}
   {...rootProps}
  >
  <input
   name={name}
   type="text"
   value={value || ''}
   theme={theme || defaultTheme}
   {...props}
  />
 )}
Input.contextTypes = {defaultTheme: React.PropTypes.object};

這個(gè) Input 組件(僅僅是示例)直接實(shí)現(xiàn)了 label/inputText 的組合:

  1. defaultTheme 是從 Context 中解構(gòu)出來的,如果 props 沒有設(shè)定 theme,就將用 defaultTheme 替代。
  2. autoFocus 需要被傳遞到底層的 inputText 而不能同時(shí)遺留給 label,因此會(huì)先通過 { theme, autoFocus, ...rootProps } = props 拿出來。

無狀態(tài)組件用來實(shí)現(xiàn) Server 端渲染也很方便,只要避免去直接訪問各種 DOM 方法。

無狀態(tài)組件與組件的生命周期方法

我們可以看到,無狀態(tài)組件就剩了一個(gè) render 方法,因此也就沒有沒法實(shí)現(xiàn)組件的生命周期方法,例如 componentDidMount, componentWillUnmount 等。那么如果需要讓我們的 Input 組件能夠響應(yīng)窗口大小的變化,那么該如何實(shí)現(xiàn)呢?這其實(shí)還是要引入“有狀態(tài)的組件”,只不過這個(gè)“有狀態(tài)的組件”可以不僅僅為 "Input" 組件服務(wù)。

const ExecutionEnvironment = require('react/lib/ExecutionEnvironment')
const defaultViewport = { width: 1366, height: 768 }; // Default size for server-side rendering

function withViewport(ComposedComponent) {
 return class Viewport extends React.Component {
  state = {
   // Server 端渲染和單元測試的時(shí)候可未必有 DOM 存在
   viewport: ExecutionEnvironment.canUseDOM ? 
    { width: window.innerWidth, height: window.innerHeight } : defaultViewport
  }
  componentDidMount() {
   // Server 端渲染是不會(huì)執(zhí)行到 `componentDidMount` 的,只會(huì)執(zhí)行到 `componentWillMount`
   window.addEventListener('resize', this.handleWindowResize)
   window.addEventListener('orientationchange', this.handleWindowResize)
  }
  componentWillUnmount() {
   window.removeEventListener('resize', this.handleWindowResize)
   window.removeEventListener('orientationchange', this.handleWindowResize)
  }
  render() {
   return <ComposedComponent {...this.props} viewport={this.state.viewport}/>
  }

  handleWindowResize() {
   const { viewport } = this.state
   if (viewport.width !== window.innerWidth || viewport.height !== window.innerHeight) {
    this.setState({ viewport: { width: window.innerWidth, height: window.innerHeight } })
   }  
  }
 }
}

*** 專業(yè)的實(shí)現(xiàn)參看 https://github.com/kriasoft/react-decorators ***

那么,下面我們就可以創(chuàng)建出一個(gè)有機(jī)會(huì)響應(yīng)窗口大小變化的 Input 組件:

const SizeableInput = withViewport(Input)
ReactDOM.render(<SizeableInput name="username" label="Username" {...props} />, mountNode)

withViewort 作為一個(gè) "高階組件" 可不僅僅是為了 Input 服務(wù)的。它可以為你需要的任何組件添加上 viewport 屬性,當(dāng)窗口大小變化時(shí),觸發(fā)重繪。

如果你用過 Redux,那么應(yīng)該也熟悉 "connect decorator" 的用法。"connect decorator" 也是一個(gè)高階組件,因此,你可以繼續(xù)來“拼湊”:

const UserNameInput = connect(
 state => ({ value: state.username })
)(SizeableInput)

高階組件的存在有兩個(gè)好處:

  • 當(dāng)寫著寫著無狀態(tài)組件的時(shí)候,有一天忽然發(fā)現(xiàn)需要狀態(tài)處理了,那么無需徹底返工:)
  • 往往我們需要狀態(tài)的時(shí)候,這個(gè)需求是可以重用的,例如上面的 withViewport,今后可以用來給其他組件(無論是否是無狀態(tài)組件)添加 viewport 屬性。

高階組件加無狀態(tài)組件,則大大增強(qiáng)了整個(gè)代碼的可測試性和可維護(hù)性。同時(shí)不斷“誘使”我們寫出組合性更好的代碼。

無狀態(tài)組件不支持 "ref"

有一點(diǎn)遺憾的是無狀態(tài)組件不支持 "ref"。原理很簡單,因?yàn)樵?React 調(diào)用到無狀態(tài)組件的方法之前,是沒有一個(gè)實(shí)例化的過程的,因此也就沒有所謂的 "ref"。

ref 和 findDOMNode 這個(gè)組合,實(shí)際上是打破了父子組件之間僅僅通過 props 來傳遞狀態(tài)的約定,是危險(xiǎn)且骯臟,需要避免。

無狀態(tài)組件尚不支持 babel-plugin-react-transform 的 Hot Module Replacement

如果你是用 Webpack 以及 HMR,用 babel-plugin-react-transform 來做 jsx 轉(zhuǎn)換等,那么當(dāng)你在編輯器中修改無狀態(tài)組件的源代碼的時(shí)候,HMR 并不會(huì)在瀏覽器中自動(dòng)載入修改后的代碼。具體問題跟蹤請(qǐng)參 https://github.com/gaearon/babel-plugin-react-transform/issues/57 。

以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • 詳解升級(jí)react-router 4 踩坑指南

    詳解升級(jí)react-router 4 踩坑指南

    本篇文章主要介紹了詳解升級(jí)react-router 4 踩坑指南,主要是對(duì)react-router 4升級(jí)的踩坑總結(jié),有興趣的可以了解一下
    2017-08-08
  • React控制元素顯示隱藏的三種方法小結(jié)

    React控制元素顯示隱藏的三種方法小結(jié)

    這篇文章主要介紹了React控制元素顯示隱藏的三種方法小結(jié),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-12-12
  • react antd checkbox實(shí)現(xiàn)全選、多選功能

    react antd checkbox實(shí)現(xiàn)全選、多選功能

    目前好像只有table組件有實(shí)現(xiàn)表格數(shù)據(jù)的全選功能,如果說對(duì)于list,card,collapse等其他組件來說,需要自己結(jié)合checkbox來手動(dòng)實(shí)現(xiàn)全選功能,這篇文章主要介紹了react antd checkbox實(shí)現(xiàn)全選、多選功能,需要的朋友可以參考下
    2024-07-07
  • React.Js添加與刪除onScroll事件的方法詳解

    React.Js添加與刪除onScroll事件的方法詳解

    這篇文章主要給大家介紹了關(guān)于React.Js添加與刪除onScroll事件的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-11-11
  • 使用React組件編寫溫度顯示器

    使用React組件編寫溫度顯示器

    這篇文章主要為大家詳細(xì)介紹了使用React組件編寫溫度顯示器,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • 解決React報(bào)錯(cuò)The?tag?is?unrecognized?in?this?browser

    解決React報(bào)錯(cuò)The?tag?is?unrecognized?in?this?browser

    這篇文章主要為大家介紹了解決React報(bào)錯(cuò)The?tag?is?unrecognized?in?this?browser示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12
  • 深入理解React調(diào)度(Scheduler)原理

    深入理解React調(diào)度(Scheduler)原理

    本文主要介紹了深入理解React調(diào)度(Scheduler)原理,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-07-07
  • ReactJS應(yīng)用程序中設(shè)置Axios攔截器方法demo

    ReactJS應(yīng)用程序中設(shè)置Axios攔截器方法demo

    這篇文章主要為大家介紹了ReactJS應(yīng)用程序中設(shè)置Axios攔截器方法demo,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12
  • React-Native中禁用Navigator手勢返回的示例代碼

    React-Native中禁用Navigator手勢返回的示例代碼

    本篇文章主要介紹了React-Native中禁用Navigator手勢返回的示例代碼,具有一定的參考價(jià)值,有興趣的可以了解一下
    2017-09-09
  • React創(chuàng)建組件的三種方式及其區(qū)別

    React創(chuàng)建組件的三種方式及其區(qū)別

    本文主要介紹了React創(chuàng)建組件的三種方式及其區(qū)別,具有一定的參考價(jià)值,下面跟著小編一起來看下吧
    2017-01-01

最新評(píng)論