這篇文章主要介紹React中無狀態(tài)組件與高階組件的示例分析,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!
創(chuàng)新互聯(lián)公司專注于企業(yè)網(wǎng)絡營銷推廣、網(wǎng)站重做改版、陵水黎族網(wǎng)站定制設計、自適應品牌網(wǎng)站建設、成都h5網(wǎng)站建設、購物商城網(wǎng)站建設、集團公司官網(wǎng)建設、外貿營銷網(wǎng)站建設、高端網(wǎng)站制作、響應式網(wǎng)頁設計等建站業(yè)務,價格優(yōu)惠性價比高,為陵水黎族等各大城市提供網(wǎng)站開發(fā)制作服務。
無狀態(tài)組件(Stateless Component) 是 React 0.14 之后推出的,大大增強了編寫 React 組件的方便性,也提升了整體的渲染性能。
無狀態(tài)組件 (Stateless Component)
function HelloComponent(props, /* context */) { return <div>Hello {props.name}</div> } ReactDOM.render(<HelloComponent name="Sebastian" />, mountNode)
HelloComponent 第一個參數(shù)是 props,第二個是 context。最后一句也可以這么寫:
ReactDOM.render(HelloComponent{ name:"Sebastian" }, mountNode)
可以看到,原本需要寫“類”定義(React.createClass 或者 class YourComponent extends React.Component)來創(chuàng)建自己組件的定義,現(xiàn)在被精簡成了只寫一個 render 函數(shù)。更值得一提的是,由于僅僅是一個無狀態(tài)函數(shù),React 在渲染的時候也省掉了將“組件類” 實例化的過程。
結合 ES6 的解構賦值,可以讓代碼更精簡。例如下面這個 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};
這個 Input 組件(僅僅是示例)直接實現(xiàn)了 label/inputText 的組合:
defaultTheme 是從 Context 中解構出來的,如果 props 沒有設定 theme,就將用 defaultTheme 替代。
autoFocus 需要被傳遞到底層的 inputText 而不能同時遺留給 label,因此會先通過 { theme, autoFocus, ...rootProps } = props 拿出來。
無狀態(tài)組件用來實現(xiàn) Server 端渲染也很方便,只要避免去直接訪問各種 DOM 方法。
無狀態(tài)組件與組件的生命周期方法
我們可以看到,無狀態(tài)組件就剩了一個 render 方法,因此也就沒有沒法實現(xiàn)組件的生命周期方法,例如 componentDidMount, componentWillUnmount 等。那么如果需要讓我們的 Input 組件能夠響應窗口大小的變化,那么該如何實現(xiàn)呢?這其實還是要引入“有狀態(tài)的組件”,只不過這個“有狀態(tài)的組件”可以不僅僅為 "Input" 組件服務。
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 端渲染和單元測試的時候可未必有 DOM 存在 viewport: ExecutionEnvironment.canUseDOM ? { width: window.innerWidth, height: window.innerHeight } : defaultViewport } componentDidMount() { // Server 端渲染是不會執(zhí)行到 `componentDidMount` 的,只會執(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è)的實現(xiàn)參看 https://github.com/kriasoft/react-decorators ***
那么,下面我們就可以創(chuàng)建出一個有機會響應窗口大小變化的 Input 組件:
const SizeableInput = withViewport(Input) ReactDOM.render(<SizeableInput name="username" label="Username" {...props} />, mountNode)
withViewort 作為一個 "高階組件" 可不僅僅是為了 Input 服務的。它可以為你需要的任何組件添加上 viewport 屬性,當窗口大小變化時,觸發(fā)重繪。
如果你用過 Redux,那么應該也熟悉 "connect decorator" 的用法。"connect decorator" 也是一個高階組件,因此,你可以繼續(xù)來“拼湊”:
const UserNameInput = connect( state => ({ value: state.username }) )(SizeableInput)
高階組件的存在有兩個好處:
當寫著寫著無狀態(tài)組件的時候,有一天忽然發(fā)現(xiàn)需要狀態(tài)處理了,那么無需徹底返工:)
往往我們需要狀態(tài)的時候,這個需求是可以重用的,例如上面的 withViewport,今后可以用來給其他組件(無論是否是無狀態(tài)組件)添加 viewport 屬性。
高階組件加無狀態(tài)組件,則大大增強了整個代碼的可測試性和可維護性。同時不斷“誘使”我們寫出組合性更好的代碼。
無狀態(tài)組件不支持 "ref"
有一點遺憾的是無狀態(tài)組件不支持 "ref"。原理很簡單,因為在 React 調用到無狀態(tài)組件的方法之前,是沒有一個實例化的過程的,因此也就沒有所謂的 "ref"。
ref 和 findDOMNode 這個組合,實際上是打破了父子組件之間僅僅通過 props 來傳遞狀態(tài)的約定,是危險且骯臟,需要避免。
無狀態(tài)組件尚不支持 babel-plugin-react-transform 的 Hot Module Replacement
如果你是用 Webpack 以及 HMR,用 babel-plugin-react-transform 來做 jsx 轉換等,那么當你在編輯器中修改無狀態(tài)組件的源代碼的時候,HMR 并不會在瀏覽器中自動載入修改后的代碼。具體問題跟蹤請參 https://github.com/gaearon/babel-plugin-react-transform/issues/57 。
以上是“React中無狀態(tài)組件與高階組件的示例分析”這篇文章的所有內容,感謝各位的閱讀!希望分享的內容對大家有幫助,更多相關知識,歡迎關注創(chuàng)新互聯(lián)行業(yè)資訊頻道!
當前標題:React中無狀態(tài)組件與高階組件的示例分析
分享路徑:http://bm7419.com/article46/jjdhhg.html
成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供建站公司、網(wǎng)站設計、網(wǎng)頁設計公司、手機網(wǎng)站建設、虛擬主機、面包屑導航
聲明:本網(wǎng)站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經(jīng)允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)