談談從0開始快速學習React Native(一)

React Native是基于React的,在開發React Native過程中少不了的需要用到React方面的知識。雖然官方也有相應的Document,但篇幅比較多,學起來比較枯燥。

我可以說是從0開始學習React Native,之前學習的人少,自己也走了不少彎路,以后能把自己的一些想法或者是學習方法寫出來分享一下,讓后來學習的同行們少走一些彎路。(最好先學習一下reactjs)

自己理解的React(我們需要了解的東西)
1.React?
2.React的特點
3.JSX語法
4.組件(Component)
5.組件的屬性、狀態

一、什么是React?

React是一個用于組建用戶界面的JavaScript庫,讓你更加簡單的方式來創建交互式用戶界面。

個人認為的優點吧:

1.React就是由許多個組件來組合而成的。
2.數據改變的時候,React能高效的更新和渲染更新的組件。
3.聲明性視圖讓你的代碼容易調試,自己能預測出效果
4.封裝管理自己的狀態組件,將他們組成復雜的界面。
5.由于組件邏輯是用JavaScript編寫的,可以輕松地通過程序傳遞大量數據,并保持DOM狀態。
6.一次學習隨時隨地可以編寫,學會了React,不僅可以輕松的開發web,也可以用于React Native來開發Android+ios應用。

二、開始學習React

使用React之前需要在React官網下載這些庫,也可以將其下載到本地去使用。
-react.js
-react-dom.js
-browser.min.js
上面一共列舉了三個庫: react.js 、react-dom.js 和 browser.min.js ,它們必須首先加載。
react.js是React的核心庫
react-dom.js是提供與DOM相關的功能
browser.min.js的作用是將JSX語法轉為JavaScript語法
這一步很消耗時間,實際上線的時候,應該將它放到服務器完成。

注意:我們實際在做React Native開發時,這些庫作為React Native核心庫已經被初始化在node_modules目錄下,所以不需要單獨下載。

使用React寫出我們非常熟悉的Hello World

 <!DOCTYPE html>
<html>
    <head>
      <meta charset="UTF-8" />
      <title>Hello React!</title> 
      <script src="build/react.js"></script>
      <script src="build/react-dom.js"></script> 
      <script src="https://npmcdn.com/babel-core@5.8.38/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>```
>在 JavaScript 代碼里寫著 XML 格式的代碼稱為 JSX,下文會介紹。為了把 JSX 轉成標準的 JavaScript,我們用`<script type="text/babel">`標簽,然后通過Babel轉換成在瀏覽器中真正執行的內容。

####注意:ReactDOM.render 是 React 的最基本方法,用于將模板轉為 HTML 語言,并插入指定的 DOM 節點。

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

上述代碼的作用是將<h1>Hello, world!</h1>插入到元素id為example的容器中。

JSX 和 HTMLJSX 是一個看起來很像 XML 的 JavaScript 語法擴展。每一個XML標簽都會被JSX轉換工具轉換成純JavaScript代碼,使用JSX,組件的結構和組件之間的關系看上去更加清晰。 JSX并不是React必須使用的,但React官方建議我們使用 JSX , 因為它能定義簡潔且我們熟知的包含屬性的樹狀結構語法。
 React.render(//使用JSX 
     <div> 
         <div> 
             <div>content</div> 
         </div>
     </div>, 
     document.getElementById('example')
  );
  React.render(//不使用JSX 
     React.createElement('div', null, 
         React.createElement('div', null, 
           React.createElement('div', null, 'content') 
         ) 
     ), 
     document.getElementById('example')
   );

HTML標簽 與 React組件 對比React 可以渲染 HTML 標簽 (strings) 或 React 組件 (classes)。 要渲染 HTML 標簽,只需在 JSX 里使用小寫字母開頭的標簽名。

      var myDivElement = <div className="foo" />;
      React.render(
         myDivElement, document.body
      );

要渲染 React 組件,只需創建一個大寫字母開頭的本地變量。

        var MyComponent = React.createClass({/*...*/});
        var myElement = <MyComponent someProperty={true} />;
        React.render(myElement, document.body);

注意:

  • React 的 JSX 里約定分別使用首字母大、小寫來區分本地組件的類和 HTML 標簽。
  • 由于 JSX 就是 JavaScript,一些標識符像 class 和 for 不建議作為 XML 屬性名。作為替代, React DOM 使用 className 和 htmlFor 來做對應的屬性。

JavaScript 表達式

屬性表達式要使用 JavaScript 表達式作為屬性值,只需把這個表達式用一對大括號 ({}) 包起來,不要用引號 ("")。

      // 輸入 (JSX):
      var person = <Person name={window.isLoggedIn ? window.name : ''} />;
      // 輸出 (JS):
      var person = React.createElement( 
          Person, 
          {
              name: window.isLoggedIn ? window.name : ''
          }
      );

子節點表達式同樣地,JavaScript 表達式可用于描述子結點:

        // 輸入 (JSX):
        var content = <Container>{window.isLoggedIn ? <Nav /> : <Login />}</Container>;
        // 輸出 (JS):var content = React.createElement( Container, null, window.isLoggedIn ? React.createElement(Nav) : React.createElement(Login));

React中注釋JSX 里添加注釋很容易;它們是 JS 表達式。需要在一個標簽的子節點內(非最外層)用 {} 包圍要注釋的部分。

      class ReactDemo extends Component { 
            render() {
                   return (  
                        <View style={styles.container}> 
                              {/*標簽子節點的注釋*/} 
                              <Text 
                                    style={styles.welcome}
                                   //textAlign='right' textShadowColor='yellow'
                                   /*
                                        color='red' 
                                        textShadowRadius='1'
                                    */ > 
                                    React Native!
                                 </Text> 
                        </View> 
                    );
             }
        }

注意:
在標簽內要使用{/*注釋的內容*/}
在標簽節點以外注釋,和通常的注釋是一樣的,多行用/*多行注釋的內容*/ 單行用//單行注釋的內

修改組件的屬性,會導致React不會對組件的屬性類型(propTypes)進行的檢查。從而引發一些預料之外的問題。

兩種寫法都能實現不推薦的:

var component = <Component />; component.props.foo = x; component.props.bar = y;

推薦做法:

var component = <Component foo={x} bar={y} />;

Component React 允許將代碼封裝成組件(Component),然后像插入普通 HTML 標簽一樣,在網頁中插入這個組件。

        var HelloMessage = React.createClass({ 
                  render: function() { 
                          return 
                                <h1>Hello {this.props.name}</h1>;
                  }
         });
          ReactDOM.render( 
                <HelloMessage name="MrQ" />,
                document.getElementById('example')
          );

上面代碼中,變量 HelloMessage 就是一個組件類。模板插入 <HelloMessage />時,會自動生成 HelloMessage 的一個實例。所有組件類都必須有自己的 render 方法,用于輸出組件。

注意

  • 組件類的第一個字母必須大寫。
  • 組件類只能包含一個頂層標簽(在開發React Native中一般是用View最外層的進行包裹)。
  • 組件的屬性(props) 我們可以通過this.props.XXX的形式獲取組件對象的屬性,對象的屬性可以任意定義,但要避免與JavaScript關鍵字沖突。
遍歷對象的屬性: this.props.children會返回組件對象的所有屬性。 React 提供一個工具方法 React.Children 來處理 this.props.children 。我們可以用 React.Children.mapReact.Children.forEach 來遍歷子節點。

React.Children.map

      array 
      React.Children.map(object children, function fn [, object thisArg])

該方法會返回一個數組。
React.Children.forEach

     React.Children.forEach(object children, function fn [, object thisArg])
       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
     );

PropTypes組件的屬性可以接受任意值,字符串、對象、函數等等都可以。有時,我們需要一種機制,驗證別人使用組件時,提供的參數是否符合要求。 組件類的PropTypes屬性,就是用來驗證組件實例的屬性是否符合要求。

      var MyTitle = React.createClass({
             propTypes: { 
                    title: React.PropTypes.string.isRequired,
             }, 
             render: function() {
                   return <h1> {this.props.title} </h1>;
             }
      });

上面的Mytitle組件有一個title屬性。PropTypes 告訴 React,這個 title 屬性是必須的,而且它的值必須是字符串。現在,我們設置 title 屬性的值是一個數值。

        var data = 123;
        ReactDOM.render( 
              <MyTitle title={data} />, 
              document.body
        );

這樣一來,title屬性就通不過驗證了。控制臺會顯示一行錯誤信息。

Warning: Failed propType: Invalid prop `title` of type `number` supplied to `MyTitle`, expected `string`.

更多的PropTypes設置,可以查看官方文檔。 此外,getDefaultProps 方法可以用來設置組件屬性的默認值。

      var MyTitle = React.createClass({
               getDefaultProps : function () {
                       return { 
                            title : 'Hello World' 
                        };
               },
               render: function() {
                       return <h1> {this.props.title} </h1>;
               }
        });
        ReactDOM.render(
               <MyTitle />,
               document.body
        );

上面代碼會輸出"Hello World"

ref 屬性(獲取真實的DOM節點)組件并不是真實的 DOM 節點,而是存在于內存之中的一種數據結構,叫做虛擬 DOM (virtual DOM)。只有當它插入文檔以后,才會變成真實的 DOM 。根據 React 的設計,所有的 DOM 變動,都先在虛擬 DOM 上發生,然后再將實際發生變動的部分,反映在真實 DOM上,這種算法叫做 DOM diff ,它可以極大提高網頁的性能表現。但是,有時需要從組件獲取真實 DOM 的節點,這時就要用到 ref 屬性。

       var MyComponent = React.createClass({ 
               handleClick: function() { 
                       this.refs.myTextInput.focus();
              },
              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')
   );

上面代碼中,組件 MyComponent 的子節點有一個文本輸入框,用于獲取用戶的輸入。這時就必須獲取真實的 DOM 節點,虛擬 DOM 是拿不到用戶輸入的。為了做到這一點,文本輸入框必須有一個 ref 屬性,然后 this.refs.[refName] 就會返回這個真實的 DOM 節點。
需要注意的是,由于 this.refs.[refName] 屬性獲取的是真實 DOM ,所以必須等到虛擬 DOM 插入文檔以后,才能使用這個屬性,否則會報錯。上面代碼中,通過為組件指定 Click 事件的回調函數,確保了只有等到真實 DOM 發生 Click 事件之后,才會讀取 this.refs.[refName] 屬性。

注意:ref屬性在開發中使用頻率很高,使用它你可以獲取到任何你想要獲取的組件的對象,有個這個對象你就可以靈活地做很多事情,比如:讀寫對象的變量,甚至調用對象的函數。

state上文講到了props,因為每個組件只會根據props 渲染了自己一次,props 是不可變的。為了實現交互,可以使用組件的 state 。this.state 是組件私有的,可以通過getInitialState()方法初始化,通過調用 this.setState() 來改變它。當 state 更新之后,組件就會重新渲染自己。 render() 方法依賴于 this.props 和 this.state ,框架會確保渲染出來的 UI 界面總是與輸入( this.props 和 this.state )保持一致。### 初始化state 通過getInitialState()方法初始化state,在組件的生命周期中僅執行一次,用于設置組件的初始化 state 。
          getInitialState:function(){ 
                return {favorite:false}; 
          }
更新 state 通過this.setState()方法來更新state,調用該方法后,React會重新渲染相關的UI。 `this.setState({favorite:!this.state.favorite});
        var FavoriteButton=React.createClass({ 
                getInitialState:function(){ 
                      return {favorite:false};
                },
                handleClick:function(event){
                      this.setState({
                          favorite:!this.state.favorite
                });
         },
         render:function(){
                 var text=this.state.favorite? 'favorite':'un favorite';
                 return ( 
                      <div type='button' onClick={this.handleClick}> {text}  </div> );
                 }
        });
```
上面代碼是一個 FavoriteButton 組件,它的 getInitialState 方法用于定義初始狀態,也就是一個對象,這個對象可以通過 this.state 屬性讀取。當用戶點擊組件,導致狀態變化,this.setState 方法就修改狀態值,每次修改以后,自動調用 this.render 方法,再次渲染組件。 
>注意:由于 this.props 和 this.state 都用于描述組件的特性,可能會產生混淆。一個簡單的區分方法是,this.props 表示那些一旦定義,就不再改變的特性,而 this.state 是會隨著用戶互動而產生變化的特性。
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,345評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,494評論 3 416
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,283評論 0 374
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,953評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,714評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,186評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,255評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,410評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,940評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,776評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,976評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,518評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,210評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,642評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,878評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,654評論 3 391
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,958評論 2 373

推薦閱讀更多精彩內容

  • React Native是基于React的,在開發React Native過程中少不了的需要用到React方面的知...
    亓凡閱讀 1,125評論 0 2
  • 原教程內容詳見精益 React 學習指南,這只是我在學習過程中的一些閱讀筆記,個人覺得該教程講解深入淺出,比目前大...
    leonaxiong閱讀 2,849評論 1 18
  • GUIDS 第一章 為什么使用React? React 一個提供了用戶接口的JavaScript庫。 誕生于Fac...
    jplyue閱讀 3,562評論 1 11
  • It's a common pattern in React to wrap a component in an ...
    jplyue閱讀 3,291評論 0 2
  • 故事簡介:家庭很富裕但高考后父母卻離婚的男生--于煜,在高考后來到了荊楚理工學院,心高氣傲內心卻很脆弱的他在接下來...
    洛莧閱讀 870評論 2 5