React要點入門學習總結

一.JSX簡介

JSX即JavaScript XML,一種在React組件內部構建標籤的類XML語法。
在不使用JSX的狀況下,React程序中建立DOM是這樣的:html

//v0.11
React.DOM.h1({className: 'title'}, 'Title');
//v0.12
React.createElement('h1', {className: 'title'}, 'Title');

若是使用JSX的方式建立節點爲:node

<h1 className="title">Title</h1>

JSX的特徵:react

  1. JSX是一種句法變換,每個JSX節點都對應着一個JavaScript函數jquery

  2. JSX即不提供也不須要運行時庫git

  3. JSX並無改變或者添加JavaScript的語義,它只是簡單的函數調用。github

代碼一

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
  </head>
  <body>
    <div id="example"></div>
    <script src="../build/react.js"></script>
    <script src="../build/react-dom.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.24/browser.min.js"></script>
    <script type="text/babel">
      ReactDOM.render(
        <h1>Hello,react!</h1>,
        document.getElementById('example')
      );
    </script>
  </body>
</html>

要點一:在整個Html文件中,只有定義了一個id爲example的div標籤,當程序運行時,JavaScript代碼執行,
React會建立新的DOM節點,也就是<h1>Hello,react!</h1>。
ReactDOM.render(newDom,parentDom);這個函數是用來對視圖進行渲染新的節點,函數的參數主要有兩個,
一個是新的節點,另外一個是新節點要放在哪一個父節點中。ajax

要點二:<script> 標籤的 type 屬性爲 "text/babel" 。這是由於 React 獨有的 JSX 語法,跟
JavaScript 不兼容。凡是使用 JSX 的地方,都要加上 type="text/babel"算法

要點三:ReactDOM.render()方法中的第一個參數,也就是新的節點,只能有一個頂層的標籤,而後裏面嵌套多個子節點,
例以下面的寫法就是不可行的:json

//Error
ReactDOM.render(
  <p>Error</P>
  <h1>Hello,react!</h1>,
  document.getElementById('example')
);

二.動態數值

代碼二

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
  </head>
  <body>
    <div id="example"></div>
    <script src="../build/react.js"></script>
    <script src="../build/react-dom.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.24/browser.min.js"></script>
    <script type="text/babel">
      var names = ['lgy','Kb'];
      ReactDOM.render(
        <div>
        {
          names.map((name) => {
            return <div>Hello,{name} !</div>
          })
        }
        </div>,
        document.getElementById('example')
      );
    </script>
  </body>
</html>

要點:經過在JavaScript中定義變量,可嵌入JSX中使用動態變量,使用的語法爲:<div>Hello,{name} !</div>api

代碼三

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
  </head>
  <body>
    <div id="example"></div>
    <script src="../build/react.js"></script>
    <script src="../build/react-dom.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.24/browser.min.js"></script>
    <script type="text/babel">
      var arr = [
        <h1>Hello react</h1>,
        <h2>Hello Node</h2>
      ];
      ReactDOM.render(
        <div>{arr}</div>,
        document.getElementById('example')
      );
    </script>
  </body>
</html>

要點:能夠經過傳入節點數組的方式,直接把數組給予新的節點,<div>{arr}</div>,JSX語法會根據數組的元素動態生成對應的子節點

三.組件構造使用

React的組件化模式是最大的亮點,組件中使用props或者state,當這兩個變量改變時,相應的DOM表現也會有所改變,這主要緣由是一個
組件是一個狀態機,對於特定的輸入,他總會返回一致的輸出。

代碼四

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
  </head>
  <body>
    <div id="example"></div>
    <script src="../build/react.js"></script>
    <script src="../build/react-dom.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.24/browser.min.js"></script>
    <script type="text/babel">
      console.log(React);
      class HelloMessage extends React.Component{
        render() {
          return <h1>Hello {this.props.name}</h1>;
        }
      }
      ReactDOM.render(
        <HelloMessage name="LGY" />,
        document.getElementById('example')
      );
    </script>
  </body>
</html>

要點一: 構造一個組件的語法使用ES6的標準進行,經過繼承React.Component,使用render() {...}進行渲染對應的標籤和變量輸出組件

要點二: 命名新構造的組件的第一個字母須要大寫!!!

要點三: 使用構造好的組件,經過使用標籤<HelloMessage name="LGY"/>,其中name是傳遞進去的參數,在內部用this.props.name進行
調用變量

四.組件的生命週期

(1)組件的三個生命週期狀態:

1.Mounting:已插入真實 DOM

2.Updating:正在被從新渲染

3.Unmounting:已移出真實 DOM

(2)組件生命週期方法:

1.componentWillMount():改方法在完成首次渲染以前被調用。是在render方法調用前能夠修改組件state的最後一次機會

2.componentDidMount():當render方法成功調用後,且DOM已經被渲染,能夠在componentDidMount內部經過this.getDOMNode()方法訪問到DOM節點

3.componentWillUpdate(object nextProps, object nextState):組件在收到新的props或者state進行渲染以前,這時調用該方法

4.componentDidUpdate(object prevProps, object prevState):這個方法可讓咱們更新已經渲染好的DOM的機會

5.componentWillUnmount():當組件的生命結束時,這個方法就會被調用

(3)兩種特殊狀態的處理函數

1.componentWillReceiveProps(object nextProps):已加載組件收到新的參數時調用

2.shouldComponentUpdate(object nextProps, object nextState):組件判斷是否從新渲染時調用

五.數據流

(1)Props:

經過props能夠把任意類型的數據傳遞給組件

var tables = [{title: 'React'}]
<TableList tables={tables} />

能夠經過this.props.tables訪問對應的屬性,然絕對不能修改。一個組件絕對不能夠本身修改本身的props!!!

(2)PropsTypes:

經過在組件中定義一個配置對象。組件初始化時,若是傳遞的屬性和propsTypes不匹配,就會打印一個console.warn日誌,
若是是可選的配置,就能夠去掉isRequired。

代碼五

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
</head>
<body>
  <div id="example"></div>
  <script src="../build/react.js"></script>
  <script src="../build/react-dom.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.24/browser.min.js"></script>
  <script type="text/babel">
    class MyTitle extends React.Component{
      render() {
        return <h1>{this.props.title}</h1>;
      }
    }
    MyTitle.propTypes = {
      title: React.PropTypes.string.isRequired
    }
    //設置默認屬性
    MyTitle.defaultProps = {
      title: "lgy"
    }
    var data = 'KB';
    ReactDOM.render(
      <MyTitle title={data}/>,
      document.getElementById('example')
    );
  </script>
</body>
</html>

要點: 示例中定義了一個組件MyTitle,其中使用propTyps對組件的屬性類型進行匹配,defaultProps對組件的屬性類型設置默認值。

代碼六

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
  </head>
  <body>
    <div id="example"></div>
    <script src="../build/react.js"></script>
    <script src="../build/react-dom.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.24/browser.min.js"></script>
    <script type="text/babel">
      class NodeList extends React.Component{
        render() {
          return (
            <ol>
            {
              React.Children.map(this.props.children,(child) => {
                return <li>{child}</li>;
              })
            }
            </ol>
          );
        }
      }
      ReactDOM.render(
        <NodeList>
          <span>Hello!</span>
          <p>LGY</p>
        </NodeList>,
        document.getElementById('example')
      );
    </script>
  </body>
</html>

要點: 經過this.props.children來獲取組件的子節點

(3)State

每一個React組件均可以擁有本身的state,state與props的區別在於前者只存在於組件的內部中,this.props
表示那些一旦定義,就再也不改變的特性,而 this.state 是會隨着用戶互動而產生變化的特性。state能夠肯定
視圖的狀態。

代碼七

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
</head>
<body>
  <div id="example"></div>
  <script src="../build/react.js"></script>
  <script src="../build/react-dom.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.24/browser.min.js"></script>
  <script type="text/babel">
    class LikeButton extends React.Component {
      constructor(props) {
        super(props);
        console.log(this);
        this.state = {liked: false};
      }
      handleClick(event) {
        console.log(this);
        this.setState({liked: !this.state.liked});
      };
      render() {
        var text = this.state.liked ? 'like' : 'haven\' t liked';
        return(
          <div>
            <input
              type="button" 
              value="Click to toggle." 
              onClick={this.handleClick.bind(this)}
            />
            <p>You {text} this.</p>
          </div>
        );
      }
    }
    ReactDOM.render(
      <LikeButton />,
      document.getElementById('example')
    );
  </script>
</body>
</html>

要點:組件LikeButton經過constructor構造函數進行初始化狀態,this.state = {liked: false} 把liked的狀態設置爲false,
而後經過handleClick綁定this,當用戶點擊按鈕時,改變liked變量的狀態,這時視圖也會隨着一塊兒改變。

六.DOM操做

組件並非真實的 DOM 節點,而是存在於內存之中的一種數據結構,叫作虛擬 DOM (virtual DOM)。只有當它
插入文檔之後,纔會變成真實的 DOM 。根據 React 的設計,全部的 DOM 變更,都先在虛擬 DOM 上發生,而後
再將實際發生變更的部分,反映在真實 DOM上,這種算法叫作 DOM diff ,它能夠極大提升網頁的性能表現。

代碼八

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
</head>
<body>
  <div id="example"></div>
  <script src="../build/react.js"></script>
  <script src="../build/react-dom.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.24/browser.min.js"></script>
  <script type="text/babel">
    var MyComponent = React.createClass({
    handleClick: function() {
      if (this.myTextInput !== null) {
        this.refs.myText.focus();
      }
    },
  render: function() {
      return (
        <div>
          <input type="text" ref="myText" />
          <input
            type="button"
            value="Focus the text input"
            onClick={this.handleClick}
          />
        </div>
      );
    }
  });
  ReactDOM.render(
    <MyComponent />,
    document.getElementById('example')
  );
  </script>
</body>
</html>

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

七.表單

代碼九

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
</head>
<body>
  <div id="example"></div>
  <script src="../build/react.js"></script>
  <script src="../build/react-dom.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.24/browser.min.js"></script>
  <script type="text/babel">
    class Input extends React.Component {
      constructor(props) {
        super(props);
        this.state = {value:'Hello!'}
      }
      handleChange(event) {
        this.setState({value:event.target.value});
      }
      render() {
        var value = this.state.value;
        return (
          <div>
            <input type="text" value={value} onChange={this.handleChange.bind(this)}/>
            <p>{value}</p>
          </div>
        );
      }
    }
    ReactDOM.render(
      <Input/>,
      document.getElementById("example")
    );
  </script>
</body>
</html>

要點:文本輸入框的值,不能用 this.props.value 讀取,而要定義一個 onChange 事件的回調函數,經過
event.target.value 讀取用戶輸入的值。textarea 元素、select元素、radio元素都屬於這種狀況

八.網絡請求

代碼十

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
</head>
<body>
  <div id="example"></div>
  <script src="../build/react.js"></script>
  <script src="../build/react-dom.js"></script>
  <script src="../node_modules/jquery/dist/jquery.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.24/browser.min.js"></script>
  <script type="text/babel">
    function get(source,callback) {
      var request = new Request(source);
      fetch(request)
      .then(res => res.json())
      .then(arr => callback(arr[0])) 
    }
    class UserGist extends React.Component {
      constructor(props) {
        super(props);
        this.state = {username: '',lastGistUrl: ''};
      }
      componentDidMount() {
        var usr = get(this.props.source,(usr) => {
          this.setState({
            username: usr.owner.login,
            lastGistUrl: usr.html_url
          });
        });
      }
    render() {
      var value = this.state.value;
      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.getElementById("example")
  );
  </script>
</body>
</html>

要點:該實例代碼使用了Fetch API來進行數據獲取,Fetch API的具體如何使用在接下來的博客文章會介紹。

github倉庫連接:https://github.com/lgybetter/ReactDemo

相關文章
相關標籤/搜索