React 入門筆記


一、什么是React

React: A JAVASCRIPT LIBRARY FOR BUILDING USER INTERFACES

上面的話直譯過來就是,React是一個用於構建用戶界面的JavaScript庫。

React起源於Facebook內部項目,后來覺得不錯,在2013年6月開源

 

二、學習React

我學習的時候是基於 React-Demos 這個阮一峰博客上寫的Demo庫以及他的博客學習的,基本上跟着Demo跑一次下來就差不多入門了。前提是你對JavaScript和DOM有一定的了解。

 

三、安裝

1.直接到官網下載

2.看着React-Demos學習的話,React-Demos中就自帶了React源碼,直接git clone或者下載zip壓縮包

 

四、HelloWorld

下面是使用React網頁的基本結構

<!DOCTYPE html>
<html>
  <head>
    <script src="../build/react.js"></script>
    <script src="../build/JSXTransformer.js"></script>
  </head>
  <body>
    <div id="helloworld"></div>
    <script type="text/jsx">
      // your code
      React.render(
        <h1>Hello, World!</h1>,
        document.getElementById('helloworld')
      );
    </script>
  </body>
</html>

注意:

1.最后的script標簽的type屬性是“text/jsx”。因為React獨有的JSX語法與JacaScript不兼容,使用JSX的地方都有顯示表明type屬性為"text/jsx"。

2.React提供的兩個庫react.js和JSXTransformer.js都必須首先加載。JSXTransformer.js的作用是件JSX語法轉為JavaScript語法,這一步實際應該放到服務器完成,因為非常耗時間。

 

上面的代碼中用到了React.render方法,這是React最基本的方法,用於將模板轉為HTML語言並插入指定的DOM節點。

 

我們看到代碼中,HTML語言直接寫在JavaScript語言中,沒有任何引號,這是JSX語法,允許HTML與JavaScript混寫。

 

五、JSX語法

把上面的HelloWorld代碼修改一下。

<!DOCTYPE html>
<html>
  <head>
    <script src="../build/react.js"></script>
    <script src="../build/JSXTransformer.js"></script>
  </head>
  <body>
    <div id="helloJSX"></div>
    <script type="text/jsx">
      // your code
      var names = ['John', 'Amin', 'Ann'];
      React.render(
        <div>
        {
          names.map(function (name) {
            return <h1>Hello, {name}!</h1>
          })
        }
        </div>,
        document.getElementById('helloJSX')
      );
    </script>
  </body>
</html>

上面這種像XML的語法叫JSX語法。

在JSX語法中,遇到HTML標簽(以<開頭)就用HTML規則解析,遇到代碼塊(以{開頭)就用JavaScript規則解析。

上面代碼運行出來就是id為helloworld的div下再嵌套着一個div,然后再嵌套三個h1標題。

 

JSX還允許在模板中直接插入JavaScript變量,變量是數組就展開數組成員。

<!DOCTYPE html>
<html>
  <head>
    <script src="../build/react.js"></script>
    <script src="../build/JSXTransformer.js"></script>
  </head>
  <body>
    <div id="helloArray"></div>
    <script type="text/jsx">
      // your code
      var arr = [
        <h1>Hello, world!</h1>,
        <h2>Hello, Amin!</h2>,
        <h3>React is awesome</h3>
      ];
      React.render(
        <div>{arr}</div>,
        document.getElementById('helloArray')
      );
    </script>
  </body>
</html>

上面代碼會在id為helloArray的div下嵌套三個套着div的標題。

我本來想看一下如果不想在標題外面再嵌套div要怎么做,暫時還沒發現。

 

六、組件(component)

<!DOCTYPE html>
<html>
  <head>
    <script src="../build/react.js"></script>
    <script src="../build/JSXTransformer.js"></script>
  </head>
  <body>
    <div id="helloComponent"></div>
    <script type="text/jsx">
      // your code
      var HelloMessage = React.createClass({
        render: function() {
          return <h1>hello, {this.props.name}</h1>;
        }
      });
      React.render(
        <HelloMessage name="John"/>,
        document.getElementById('helloComponent')
      );
    </script>
  </body>
</html>

React允許代碼封裝成組件,在網頁中插入組件就像插入普通HTML標簽一樣。

React.createClass方法是用來生成一個組件類,上面的HelloMessage就是這個方法生成的一個組件類。在模板插入<HelloMessage />時和插入普通的HTML標簽一樣,但是會自動生成HelloMessage這個組件類的一個實例。在組件類中應該有自己的render方法來輸出組件。

組件可以加入任意的屬性,和HTML標簽的用法一樣。上面的HelloMessage組件中就有一個name屬性。組件屬性在組件類的this.props對象上可以獲取。

添加組件屬性的時候需要注意不要和JavaScript保留字沖突。如果要用到class和for應該這么寫:

var MyComponent = React.createClass({ 
  render: function() { 
    return <div className="first"><span>A Span</span></div>;
  }  
});

 

this.props對象屬性基本上和組件屬性對應,除了this.props.children屬性,它表示的意思是組件的所有子節點。

見下面代碼

<!DOCTYPE html>
<html>
  <head>
    <script src="../build/react.js"></script>
    <script src="../build/JSXTransformer.js"></script>
  </head>
  <body>
    <script type="text/jsx">
      // your code
      var NoteList = React.createClass({
        render: function() {
          return (
          <ol>
            {
              this.props.children.map(function (child) {
                return <li>{child}</li>;
              })
            }
          </ol>
          );
        }
      });
      React.render(
        <NoteList>
          <span>Hello, world!</span>
          <span>Hello, Amin!</span>
          <span>Hello, Ann!</span>
        </NoteList>,
        document.body
      );
    </script>
  </body>
</html>

NoteList組件類通過this.props.children讀取NoteList組件實例下的三個span子節點,然后重新進行轉化再插入到body中。

注意子節點必須多於1個,this.props.children才會是一個數組,當它是數組時才能用map方法,否則會報錯。

 

我們需要知道,組件並不是真實的DOM節點,它是存在於內存中叫虛擬DOM(virtual DOM)的一種數據結構。組件插入文檔中以后才會成為真實的DOM節點。

根據React的diff算法,DOM變動都先在虛擬DOM上發生,然后將發生變動部分反映到真實DOM上。

如果需要從組件中獲取真實DOM節點,需要用到的方法叫React.findDOMNode.

<!DOCTYPE html>
<html>
  <head>
    <script src="../build/react.js"></script>
    <script src="../build/JSXTransformer.js"></script>
  </head>
  <body>
    <div id="example"></div>
    <script type="text/jsx">
      // your code
      var MyComponent = React.createClass({
        handleClick: function() {
          React.findDOMNode(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>
          );
        }
      });
      React.render(
        <MyComponent />,
        document.getElementById('example')
      );
    </script>
  </body>
</html>

我對上面代碼的理解是,在組件MyComponent的子節點中有一個文本輸入框,用於獲取用戶輸入,onClick綁定的事件是組件中的handleClick,讓文本框獲得焦點。

這時就需要獲得真實的DOM節點,為了做到這點,首先文本輸入框要有一個ref屬性,我對ref屬性的理解是通過這個屬性文本輸入框被分配了一個名字,通過this.refs.[refName]就能指向這個虛擬DOM的子節點,最后通過React.findDOMNode方法獲取真實DOM節點。

 

React把組件看成一個狀態機,一開始有一個初始狀態,組件與用戶互動導致狀態變化的話,會觸發重新渲染UI。

<!DOCTYPE html>
<html>
  <head>
    <script src="../build/react.js"></script>
    <script src="../build/JSXTransformer.js"></script>
  </head>
  <body>
    <div id="state"></div>
    <script type="text/jsx">
      // your code
      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>
          );
        } 
      });
      
      React.render(
        <LikeButton />,
        document.getElementById('state')
      );
    </script>
  </body>
</html>

上面的效果就是你點擊div里面的文字會進行切換。

LikeButton組件中的getInitialState方法定義初始狀態,這個對象通過this.state讀取。每次點擊都會導致狀態變化,this.setState方法用於修改狀態值,每次修改之后都會自動調用this.render方法,再次渲染組件。

當組件的特性是會隨着與用戶互動而產生變化時,我們應該使用this.state,而不是this.props

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM