React JS 基礎知識17條

来源:http://www.cnblogs.com/yinluhui0229/archive/2016/07/29/5719499.html
-Advertisement-
Play Games

1. 基礎實例 說明: (1).react.js:React 的核心庫。 (2).react-dom.js:提供與 DOM 相關的功能。 (3).Browser.js:將 JSX 語法轉為 JavaScript 語法。這一步很消耗時間,實際上線的時候,應該將它放到伺服器完成,操作如下: $ babe ...


1. 基礎實例

    <!DOCTYPE html>
    <html>
      <head>
        <script src="../build/react.js"></script>
        <script src="../build/react-dom.js"></script>
        <script src="../build/browser.min.js"></script>
      </head>
      <body>
        <div id="example"></div>
        <script type="text/babel">
          ReactDOM.render(
            <h1>Hello, world!</h1>,
            document.getElementById('example')
          );
        </script>
      </body>
    </html>

 

說明:

(1).react.js:React 的核心庫。
(2).react-dom.js:提供與 DOM 相關的功能。
(3).Browser.js:將 JSX 語法轉為 JavaScript 語法。這一步很消耗時間,實際上線的時候,應該將它放到伺服器完成,操作如下:
    $ babel src --out-dir build
  將 src 子目錄的 js 文件進行語法轉換,轉碼後的文件全部放在 build 子目錄。
(4).text/babel:凡是使用 JSX 的地方,都要加上 type="text/babel"。

 

2. ReactDOM.render()

用於將模板轉為 HTML 語言,並插入指定的 DOM 節點。

ReactDOM.render(
            <h1>Hello, world!</h1>,
            document.getElementById('example')
          );

 

  

3. JSX 允許直接在模板插入 JavaScript 變數。如果這個變數是一個數組,則會展開這個數組的所有成員

    var arr = [
      <h1>Hello world!</h1>,
      <h2>React is awesome</h2>,
    ];
    ReactDOM.render(
      <div>{arr}</div>,
      document.getElementById('example')
    );

 

  

4. React.createClass()
  生成一個組件類。

5. class 屬性需要寫成 className ,for 屬性需要寫成 htmlFor ,這是因為 class 和 for 是 JavaScript 的保留字。

6. React.Children.map()
  用來遍歷子節點,而不用擔心 this.props.children 的數據類型是 undefined 、object 、array。
  this.props.children 的值有三種可能:
  數據類型undefined:當前組件沒有子節點;
  數據類型object:有一個子節點;
  數據類型array: 有多個子節點。

var NotesList = React.createClass({
      render: function() {
        return (
          <ol>
          {
            React.Children.map(this.props.children, function (child) {
              return <li>{child}</li>;
            })
          }
          </ol>
        );
      }
    });
    ReactDOM.render(
      <NotesList>
        <span>hello</span>
        <span>world</span>
      </NotesList>,
      document.body
    );

 

姊妹屬性還有
React.Children.map :遍歷,返回對象
React.Children.forEach :遍歷,不返回對象
React.Children.count :返回 children 當中的組件總數
React.Children.only :返回 children 中僅有的子級。否則拋出異常

7. 組件類的 PropTypes 屬性,就是用來驗證組件實例的屬性是否符合要求

    var MyTitle = React.createClass({
      propTypes: {
        title: React.PropTypes.string.isRequired,//只接受string類型的,且必須傳
      },

      render: function() {
         return <h1> {this.props.title} </h1>;
       }
    });

 

姊妹屬性:

React.PropTypes.array
React.PropTypes.bool
React.PropTypes.func
React.PropTypes.number
React.PropTypes.object
React.PropTypes.string
React.PropTypes.node // 所有可以被渲染的對象:數字,字元串,DOM 元素或包含這些類型的數組。
React.PropTypes.element // React 元素
React.PropTypes.instanceOf(Message) // 用 JS 的 instanceof 操作符聲明 prop 為類的實例
React.PropTypes.oneOf(['News', 'Photos']) // 用 enum枚舉 來限制 prop 只接受指定的值。
React.PropTypes.oneOfType([React.PropTypes.string,React.PropTypes.number,React.PropTypes.instanceOf(Message)]) // 指定的多個對象類型中的一個
React.PropTypes.arrayOf(React.PropTypes.number) // 指定類型組成的數組(如只接受數字組成的數組)
React.PropTypes.objectOf(React.PropTypes.number) // 指定類型的屬性構成的對象(如只接受數字組成的對象)
React.PropTypes.shape({color: React.PropTypes.string,fontSize: React.PropTypes.number}) // 特定形狀參數的對象(字元串顏色,數字字體)

以後任意類型加上 'isRequired' 來使 prop 不可空。
React.PropTypes.func.isRequired
React.PropTypes.any.isRequired //不可空的任意類型

 

8. getDefaultProps()設置組件屬性預設值

    var MyTitle = React.createClass({
      getDefaultProps : function () {
        return {
          title : 'Hello World'//沒傳遞就用預設值
        };
      },

      render: function() {
         return <h1> {this.props.title} </h1>;
       }
    });

    ReactDOM.render(
      <MyTitle />,
      document.body
    );

 

 

9. ref 獲取真實DOM

React組件生成的是虛擬DOM,只有插入到頁面中後才能變成真實的DOM。
任何DOM變動,都先在虛擬DOM上發生,然後再將實際發生變動的部分,反映在真實 DOM上,這種演算法叫做 DOM diff ,它可以極大提高網頁的性能表現。
但是,有時需要從組件獲取真實 DOM 的節點,這時就要用到 ref 屬性。

    var MyComponent = React.createClass({
      handleClick: function() {
        this.refs.myTextInput.focus();// this.refs.myTextInput 獲取真實的Input DOM
      },
      render: function() {
        return (
          <div>
            <input type="text" ref="myTextInput" />
            <input type="button" value="Focus the text input" onClick={this.handleClick} />
          </div>
        );
      }
    });

    ReactDOM.render(
      <MyComponent />,
      document.getElementById('example')
    );

 

說明:
(1) 由於真實DOM發生在虛擬DOM之後,所以this.refs.[refName]必須等到虛擬 DOM 插入文檔以後,才能使用這個屬性,否則會報錯。
(2) ref是獲取當前節點的真實DOM;this.getDOMNode()是獲取真個組件的真實DOM;兩者都必須要在組件載入完成後使用。

10. React 事件

剪貼板事件:
onCopy
onCut
onPaste
鍵盤事件:
onKeyDown
onKeyPress
onKeyUp
滑鼠事件:
onClick
onDoubleClick
onDrag
onDragEnd
onDragEnter
onDragExit
onDragLeave
onDragOver
onDragStart
onDrop
onMouseDown
onMouseEnter
onMouseLeave
onMouseMove
onMouseOut
onMouseOver
onMouseUp
onWheel :滑鼠滾輪滾動事件
觸摸事件:
onTouchCancel
onTouchEnd
onTouchMove
onTouchStart
焦點事件:
onFocus
onBlur
表單事件:
onChange
onInput
onSubmit
UI 事件:
onScroll
事件說明參考:http://reactjs.cn/react/docs/events.html

11. this.state 和 this.props
  每個React組件都是一個狀態機,一旦狀態改變(與用戶發生交互)就會重新渲染組件,這就是 this.state。
  每個組件又有初始化所需要的數據,一旦初始化完成,該數據就不再變動,這就是 this.props。

    var LikeButton = React.createClass({
      getInitialState: function() {
        return {liked: false};
      },
      handleClick: function(event) {
        this.setState({liked: !this.state.liked});
      },
      render: function() {
        var text = this.state.liked ? 'like' : 'haven\'t liked';
        return (
          <p onClick={this.handleClick}>
            You {text} this. Click to toggle.
          </p>
        );
      }
    });

    ReactDOM.render(
      <LikeButton />,
      document.getElementById('example')
    );

 

 

12. 表單
  表單包括:input、textarea、checkbox、radio、option.
  監聽表單組件變化使用 onChange 事件,通過以下屬性獲取對應值:
    value:表單input、textarea;
    checked:表單checkbox、radio;
    selected:表單option。

    var Input = React.createClass({
      getInitialState: function() {
        return {value: 'Hello!'};
      },
      handleChange: function(event) {
        this.setState({value: event.target.value});
      },
      render: function () {
        var value = this.state.value;
        return (
          <div>
            <input type="text" value={value} onChange={this.handleChange} />
            <p>{value}</p>
          </div>
        );
      }
    });
    ReactDOM.render(<Input/>, document.body);

 

  

13. 組件生命周期

生命周期三個狀態:
(1)Mouting:已插入真實 DOM
(2)Updating:正在被重新渲染
(3)Unmounting:已移出真實 DOM
三個狀態對應 5 個函數 + 2 個特殊處理:
(1)componentWillMount:初始化渲染之前調用(只在第一次渲染時調用,後續重新渲染、修改props/state 都不在調用)。
              允許調用setState(),組件直接使用新的state,而不會引起第二次渲染。
(2)componentDidMount:初始化渲染之後調用(只在第一次渲染時調用,後續重新渲染、修改props/state 都不在調用)。
              jQuery操作DOM(如ref、getDOMNode使用)、調用外部JS方法(通過props傳遞)等都可以在這裡操作。
(3)componentWillUpdate:修改props/state 重新渲染之前調用(第一次渲染時不調用)。
                不允許調用setState(),會造成死迴圈。
(4)componentDidUpdate:修改props/state 重新渲染之後調用(第一次渲染時不調用)。
               不允許調用setState(),會造成死迴圈。
               jQuery操作DOM(如ref、getDOMNode使用)、調用外部JS方法(通過props傳遞)等都可以在這裡操作。
(5)componentWillUnmount:組件被移除時調用(比如在div中渲染組件1,然後再渲染組件2,此時組件1被移除)。
                 執行任何必要的清理,比如無效的定時器,或者清除在 componentDidMount 中創建的 DOM 元素。

(6)componentWillReceiveProps(object nextProps):修改props 重新渲染 之前調用(第一次渲染時不調用;如果props和之前一樣,也會執行)。
                           允許調用setState(),組件直接使用新的state,而不會引起第二次渲染。
                           該方法中this.props可以獲取老props,參數nextProps才表示新的props。
(7)shouldComponentUpdate:是否需要重新渲染組件。修改props/state 重新渲染之前調用(第一次渲染時不調用)。
                true 表示需要重新渲染;false 表示不需要重新渲染,即不會調用後續的componentWillUpdate 和 componentDidUpdate。
                優化性能的關鍵函數:該方法可以實現新老props 和 state 的比對邏輯,自定義是否重新渲染。組件較多時,可提升性能。
總結:
  各個生命周期函數的先後順序:
  初始化渲染階段:componentWillMount > componentDidMount
  修改state 階段:shouldComponentUpdate > componentWillUpdate > componentDidUpdate
  修改props 階段:componentWillReceiveProps > shouldComponentUpdate > componentWillUpdate > componentDidUpdate
  舊組件卸載階段:舊組件 componentWillUnmount > 新組件生命周期
生命周期測試實例:

    <!DOCTYPE html>
    <html>
      <head>
        <script src="../build/react.js"></script>
        <script src="../build/react-dom.js"></script>
        <script src="../build/browser.min.js"></script>
      </head>
      <body>
        <div id="example"></div>    
        <script type="text/babel">
          var Hello = React.createClass({
            getInitialState: function () {
              console.log('組件1getInitialState被執行');
              return {
                name: this.props.name
              };
            },
            componentWillMount: function() {
              console.log('組件1:componentWillMount');
            },
            componentDidMount: function() {
              console.log('組件1:componentDidMount');
            },
            componentWillUpdate: function() {
              console.log('組件1:componentWillUpdate');
              // this.setState({name: '內部componentWillUpdate更新state'});//會造成死迴圈,一直載入組件
            },
            componentDidUpdate: function() {
              console.log('組件1:componentDidUpdate');
            },
            componentWillUnmount: function() {
              console.log('組件1:被卸載:componentWillUnmount');
            },
            componentWillReceiveProps: function(nextProps) {
              console.log('組件1:componentWillReceiveProps:老props:'+this.props.name+';新props:'+nextProps.name);
            },
            shouldComponentUpdate: function() {
              console.log('組件1:shouldComponentUpdate');
              return true;// true 表示需要重新渲染;false 表示不需要重新渲染,即不會調用後續的componentWillUpdate和componentDidUpdate。
            },
            handleClick: function(event) {
              console.log('修改state重新渲染組件1:');
              this.setState({name: '內部更新state'});
            },
            
            render: function () {
              return (
                  <div onClick={this.handleClick}>
                    Hello {this.state.name}
                  </div>
              );
            }
          });

          var Hello2 = React.createClass({
            getInitialState: function () {
              console.log('組件2:getInitialState被執行');
              return {
                name: this.props.name
              };
            },
            componentWillMount: function() {
              console.log('組件2:componentWillMount');
            },
            componentDidMount: function() {
              console.log('組件2:componentDidMount');
            },
            componentWillUpdate: function() {
              console.log('組件2:componentWillUpdate');
            },
            componentDidUpdate: function() {
              console.log('組件2:componentDidUpdate');
            },
            componentWillUnmount: function() {
              console.log('組件2:被卸載:componentWillUnmount');
            },
            componentWillReceiveProps: function(nextProps) {
              console.log('組件2:componentWillReceiveProps:老props:'+this.props.name+';新props:'+nextProps.name);
            },
            shouldComponentUpdate: function() {
              console.log('組件2:shouldComponentUpdate');
              return true;
            },
            
            render: function () {
              return (
                  <div>
                    Hello {this.state.name}
                  </div>
              );
            }
          });

          ReactDOM.render(
            <Hello name="world"/>,
            document.getElementById('example')
          );

          setTimeout(function(){
            console.log('修改props重新渲染組件1:');
            ReactDOM.render(
              <Hello name="world2"/>,
              document.getElementById('example')
            );  
          }, 3000)

          setTimeout(function(){
            console.log('初始化渲染新組件2:');
            ReactDOM.render(
              <Hello2 name="組件2 world2"/>,
              document.getElementById('example')
            );
          }, 6000)
        </script>
      </body>
    </html>

 


14. React組件樣式

React採用行內樣式,它接受的必須是一個對象,行如:
style={{display:'none'}}
第一重大括弧表示這是 JavaScript 語法,第二重大括弧表示樣式對象。
說明:
(1)React 行內樣式採用駝峰形成,且不支持CSS中的'-'形式表示,如z-index 需寫成 zIndex。
(2)瀏覽器首碼的樣式(如-webkit-transition),首字母必須大寫,但是ms 開頭的例外。

var divStyle = {
              color: 'white',
              zIndex: 1000,
              paddingTop:"10px",
              backgroundImage: 'url(' + imgUrl + ')',
              WebkitTransition: 'all', // 註意這裡的首字母'W'是大寫
              msTransition: 'all' // 'ms'是唯一一個首字母需要小寫的瀏覽器首碼
            };
React.render(<div style={divStyle}>Hello World!</div>, mountNode);

 

15. Ajax請求

在實際項目中,我們通常是只把React 用於DOM渲染,而Ajax請求和邏輯判斷放在外部JS中。
如果想在React組件中調用Ajax,可以在 componentDidMount 方法中發起 Ajax 請求,等到請求成功,再用 this.setState 方法重新渲染 UI。

    var UserGist = React.createClass({
      getInitialState: function() {
        return {
          username: '',
          lastGistUrl: ''
        };
      },
      componentDidMount: function() {
        $.get(this.props.source, function(result) {
          var lastGist = result[0];
          if (this.isMounted()) {
            this.setState({
              username: lastGist.owner.login,
              lastGistUrl: lastGist.html_url
            });
          }
        }.bind(this));
      },
      render: function() {
        return (
          <div>
            {this.state.username}'s last gist is
            <a href={this.state.lastGistUrl}>here</a>.
          </div>
        );
      }
    });
    ReactDOM.render(
      <UserGist source="https://api.github.com/users/octocat/gists" />,
      document.body
    );

 

16. getInitialState()
  初始化渲染之前調用(只在第一次渲染時調用,後續重新渲染、修改props/state 都不再調用)。
  所以 getInitialState 中使用props 賦值時,後續重新渲染組件,state 的值將不會被新 props 覆蓋。
  getInitialState 的執行早於生命周期中的其他方法。

17. getDOMNode()
  獲取 React 組件的 DOM 結構。一般我們會在 componentDidMount 、componentDidUpdate 中使用,用於調用調用第三JS組件(因為第三JS組件都需要DOM結構)。
  參考:http://blog.csdn.net/lihongxun945/article/details/46640225

整理自:http://www.ruanyifeng.com/blog/2015/03/react.html


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 基於 Angularjs&Node.js 雲編輯器架構設計及開發實踐 ...
  • 一、概述 Redis3.0版本之後支持Cluster. 1.1、redis cluster的現狀 目前redis支持的cluster特性: 1):節點自動發現 2):slave->master 選舉,集群容錯 3):Hot resharding:線上分片 4):進群管理:cluster xxx 5) ...
  • 畢業到轉行以來有一年時間了,成為一名程式猿也有大半年了,之前在新浪上隨便寫寫簡單的學習過程,感覺不夠像那麼回事,現在接觸前端也有一段時間了,也做過幾個項目,認識到可以拓展的實在太多了,希望從這裡起步,踏踏實實,記錄好點點滴滴。 HHL Gulp使用步驟: 1 安裝node(npm),全局安裝,我使用 ...
  • 昨天公司說官網的登陸註冊每次要跳轉到另一個界面,能不能做一個簡單的,在界面彈出一個框框登陸,我想了想做了這麼一個案例,大家來看看成不成 貼上代碼,實現了在同一個彈出窗上載入了登陸註冊功能!可自由點擊!當然樣式醜了一些!還請見諒!demo在下麵 1這裡是html內容 2接下來是樣式css 後面更上js ...
  • 收拾心情,學習學習js!總結下自己的學習所得! 現有的有三種方法可以獲取元素的節點,分別是通過元素ID,通過標簽名和類名來獲取的 1.GetElmentById:將返回一個與那個有給定ID屬性的值的元素節點對應的對象,方法只有一個參數,元素的id屬性的值必須放在單引號或雙引號里 2.GetElmen ...
  • 一、H5有哪些新特性,移除了哪些元素?如何處理h5新標簽的瀏覽器相容性問題,如何區分html和html5 1. html5不在是SGL(通用標記語言)的一個子集,而包含了:圖像、位置、存儲、多任務等功能 2. 新增的圖像為canvas類,媒體回放video和audio元素;本地離線存儲localSt ...
  • 眾所周知,在jQuery語法中,$符號是jQuery的簡寫方式。但在某些情況下,可能需要在同一個頁面引入其他javascript庫(比如Prototype)。因為$簡短方便,很多的庫也是使用$符號。為了避免名稱衝突,jQuery提供了noConflict()方法來解決這個問題。調用該方法可以把對$標 ...
  • 1.字元串的不可變性 字元串定義了後,會一直占據記憶體空間,企鵝該處記憶體空間(棧)不可被重新賦值。 2.短路運算 ||、&& 二元運算符,返回參與運算的操作數的原值(原數據類型和原數據), 運算結束後,返回導致運算結束的那個操作數。 3.三元運算符 code1?code2:code3; 與if-els ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...