<span id="mktg5"></span>

<i id="mktg5"><meter id="mktg5"></meter></i>

        <label id="mktg5"><meter id="mktg5"></meter></label>
        最新文章專題視頻專題問答1問答10問答100問答1000問答2000關鍵字專題1關鍵字專題50關鍵字專題500關鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關鍵字專題關鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
        問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
        當前位置: 首頁 - 科技 - 知識百科 - 正文

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

        來源:懂視網 責編:小采 時間:2020-11-27 22:10:03
        文檔

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

        React 無狀態組件(Stateless Component) 與高階組件:無狀態組件(Stateless Component) 是 React 0.14 之后推出的,大大增強了編寫 React 組件的方便性,也提升了整體的渲染性能。 無狀態組件 (Stateless Component) function HelloComponent(props, /* context */) {
        推薦度:
        導讀React 無狀態組件(Stateless Component) 與高階組件:無狀態組件(Stateless Component) 是 React 0.14 之后推出的,大大增強了編寫 React 組件的方便性,也提升了整體的渲染性能。 無狀態組件 (Stateless Component) function HelloComponent(props, /* context */) {

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

        無狀態組件 (Stateless Component)

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

        HelloComponent 第一個參數是 props,第二個是 context。最后一句也可以這么寫:

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

        可以看到,原本需要寫“類”定義(React.createClass 或者 class YourComponent extends React.Component)來創建自己組件的定義,現在被精簡成了只寫一個 render 函數。更值得一提的是,由于僅僅是一個無狀態函數,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 組件(僅僅是示例)直接實現了 label/inputText 的組合:

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

        無狀態組件用來實現 Server 端渲染也很方便,只要避免去直接訪問各種 DOM 方法。

        無狀態組件與組件的生命周期方法

        我們可以看到,無狀態組件就剩了一個 render 方法,因此也就沒有沒法實現組件的生命周期方法,例如 componentDidMount, componentWillUnmount 等。那么如果需要讓我們的 Input 組件能夠響應窗口大小的變化,那么該如何實現呢?這其實還是要引入“有狀態的組件”,只不過這個“有狀態的組件”可以不僅僅為 "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 端渲染是不會執行到 `componentDidMount` 的,只會執行到 `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 } })
         } 
         }
         }
        }
        
        

        *** 專業的實現參看 https://github.com/kriasoft/react-decorators ***

        那么,下面我們就可以創建出一個有機會響應窗口大小變化的 Input 組件:

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

        withViewort 作為一個 "高階組件" 可不僅僅是為了 Input 服務的。它可以為你需要的任何組件添加上 viewport 屬性,當窗口大小變化時,觸發重繪。

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

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

        高階組件的存在有兩個好處:

      1. 當寫著寫著無狀態組件的時候,有一天忽然發現需要狀態處理了,那么無需徹底返工:)
      2. 往往我們需要狀態的時候,這個需求是可以重用的,例如上面的 withViewport,今后可以用來給其他組件(無論是否是無狀態組件)添加 viewport 屬性。
      3. 高階組件加無狀態組件,則大大增強了整個代碼的可測試性和可維護性。同時不斷“誘使”我們寫出組合性更好的代碼。

        無狀態組件不支持 "ref"

        有一點遺憾的是無狀態組件不支持 "ref"。原理很簡單,因為在 React 調用到無狀態組件的方法之前,是沒有一個實例化的過程的,因此也就沒有所謂的 "ref"。

        ref 和 findDOMNode 這個組合,實際上是打破了父子組件之間僅僅通過 props 來傳遞狀態的約定,是危險且骯臟,需要避免。

        無狀態組件尚不支持 babel-plugin-react-transform 的 Hot Module Replacement

        如果你是用 Webpack 以及 HMR,用 babel-plugin-react-transform 來做 jsx 轉換等,那么當你在編輯器中修改無狀態組件的源代碼的時候,HMR 并不會在瀏覽器中自動載入修改后的代碼。具體問題跟蹤請參 https://github.com/gaearon/babel-plugin-react-transform/issues/57 。

        聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

        文檔

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

        React 無狀態組件(Stateless Component) 與高階組件:無狀態組件(Stateless Component) 是 React 0.14 之后推出的,大大增強了編寫 React 組件的方便性,也提升了整體的渲染性能。 無狀態組件 (Stateless Component) function HelloComponent(props, /* context */) {
        推薦度:
        標簽: co 組件 React
        • 熱門焦點

        最新推薦

        猜你喜歡

        熱門推薦

        專題
        Top
        主站蜘蛛池模板: 日韩成人免费在线| 91福利免费体验区观看区| 最近免费中文字幕4| 亚洲av无码一区二区三区观看| 一级毛片aaaaaa免费看| 亚洲动漫精品无码av天堂| 少妇性饥渴无码A区免费 | 亚洲AV无码精品国产成人| 一二三四在线观看免费高清中文在线观看| 日本久久久久亚洲中字幕| 无码精品一区二区三区免费视频| 亚洲综合一区二区精品导航| 免费在线视频你懂的| 亚洲精品高清国产麻豆专区| 5g影院5g天天爽永久免费影院| 国产v亚洲v天堂a无| 免费羞羞视频网站| 一级黄色免费大片| 亚洲av无码一区二区三区不卡| 一区二区三区观看免费中文视频在线播放 | 免费无码H肉动漫在线观看麻豆| 亚洲精品高清国产一线久久| 四虎影视在线影院在线观看免费视频 | 免费可以在线看A∨网站| 亚洲精品V天堂中文字幕| 免费播放特黄特色毛片| 成在人线av无码免费高潮水| 亚洲视频在线一区| 18禁成年无码免费网站无遮挡| 色吊丝免费观看网站| 亚洲精品美女久久久久99| 亚洲一区二区三区免费观看 | 亚洲欧洲久久精品| 国产女高清在线看免费观看| GOGOGO高清免费看韩国| 亚洲视频手机在线| 免费中文字幕在线| 日韩午夜理论免费TV影院| 亚洲AV成人精品日韩一区 | 亚洲人成片在线观看| 免费va在线观看|