React入門與實踐

前言

在騰訊應用寶前端分享會上分享了react,現將資料整理成這篇文章,但願對react的初學者可以有所幫助;若是文中有描述不恰當或者錯誤的地方,請望斧正。javascript

1. 爲何使用react

react 是facebook在2013年開源的一個javascript庫,主要用來快速的構建頁面,使用react主要有如下兩個緣由:html

  • 簡單的響應式更新。在傳統的javascript中,當頁面的數據發生變化的時候,咱們除了要關注數據的變化,還要更新對應的dom結構,好比一個頁面的簡單的一個標題This is a title,當其中的內容改成hello world的時候,咱們須要以下的操做:
    <h1>This is a title</h1>
    <script>
    var data="hello world";//在實際中是從後臺獲取數據
    var h1=document.querySelector("h1");
    h1.innerHTML=data;//關注dom結構的變化
    </script>
    若是使用react 的話,只須要將數據設置進去,不須要關注dom結構的變化。
  • 組件化。在react中,咱們看到的每個頁面其實都是由一個個組件:header,content,footer等組成,這樣能夠快速的構建頁面,並且還利於組件的複用。

2. react基礎

2.1 概覽

學習編程語言C++,java可能都是hello world提及的,先看一個簡單的hello world的例子:前端

<!-- javacript files-->
    <script src="lib/react.js"></script>
    <script src="lib/react-dom.js"></script>
    <script src="lib/browser.min.js"></script>
    //...
    <div id="app"></div>
    <script type="text/babel">
        var HelloWorld = React.createClass({
        render: function() {
        return <h2>Hello World</h2>
        }
    })
      const app =document.getElementById("app");
    ReactDOM.render(<HelloWorld  />, app);
    </script>

在上面的代碼中,咱們看到引入了兩個庫:react.js,react-dom.js,其實使用react的核心庫,在0.14版本以前是一個文件,以後分紅了兩個,react.js包括了組件相關定義的屬性、方法,如:react.createClass,react.Componet等;react-dom.js主要是包括了將一個react組件渲染到頁面成爲真實dom的相關屬性,例如:reactDOM.render,findDOMNode。使用react構建一個組件分爲如下兩步:
(1)定義一個組件,並給組件一個名稱;
(2)使用reactDOM.render()方法將組件渲染到頁面上。html5

2.2 組件定義的兩種方式

上面有提到組件,那麼react怎麼定義一個組件呢。有兩種方式定義:React.createClass()與class的方式。java

React.createClass

這是是react最先的版本提出的一個建立方式,使用的方式是在rener中返回咱們須要在頁面上看到的dom結構,代碼如上圖的helloworld例子所示。react

class

第二種方式是使用class的方式,這多是跟es6相契合吧,一個比較建議使用這樣的方式;大致語法是 class componentName extends React.Component(完整代碼見附件demo01中的helloworld.html)。webpack

class HelloWorld extends React.Component {
            render(){
                return (
                <h2>Hello World!</h2>
                );
            }
        }

2.3 state vs props

在組件定義後,其組件的數據是咱們關注的焦點。react中定義了兩個屬性來描述組件的數據props與state;咱們能夠將一個組件想象成一個函數,其中props就是傳遞的參數而且不能夠在函數內修改;而state就是其中定義的變量,咱們能夠對其中的變量進行維護。es6

export default class Article extends React.Component {
  render() {
    const { title } = this.props;
    return (
      <div >
        <h4>{title}</h4>
   //...
      </div>
    );
  }
}
<Article  title={title}/>

  

咱們只須要傳遞標題的值就能夠了,不須要進行其餘的操做,所以使用props。web

  constructor() {
    super();
    this.state = {
      title: "Welcome",

    };
  }
<Header changeTitle={this.changeTitle.bind(this)} title={this.state.title} />

  

這個裏面的標題是獲取input輸入框的值,所以設置爲state。演示的效果以下:
ajax

咱們可能提出疑問,就是若是咱們將一個函數B嵌入到另外一個函數A中,在A中設置一個變量(state),那麼B中就可使用參數(props)的形式了,的確是可行的,這是兩種不一樣的組件:smart component,dumb component.能夠參考Dan的文章 Presentational and Container Components

2.4 react中的交互

react中實現事件綁定的方式是很是簡單的,只須要在對應的標籤中使用駝峯命名法給其一個綁定的函數便可。最多見的就是一個輸入框,咱們須要獲取其值,所以能夠給onChange綁定一個事件。其步驟以下:

  1. 定義一個handleChange函數
  2. 在對應的input 中加入函數的綁定input onChange=handleChange(詳細代碼參見react-webpack)
    export default class Header extends React.Component {
    handleChange(e) {
    const title = e.target.value;
    this.props.changeTitle(title);
    }
    render() {
        <input value={this.props.title} onChange={this.handleChange.bind(this)} />   
    }
    }
      

2.5 生命週期

一個react組件有三種狀態:mounting,updating,unmounting
mounting:React Component被render解析生成對應的dom節點並被插入瀏覽器的DOM結構的過程。
updating:當一個組件的狀態state發生變化的時候,會進行從新的render過程。
unmounting:是指一個mounted的React Component對應的DOM節點被從DOM節點移除的過程。

 

 

其每個生命狀態都有封裝對應的hook函數,咱們能夠經過狀態的變化過程來進行數據的加載、修改、移除等。以實現頁面的初始化和頁面數據的更新。以mouting狀態爲例,在組件渲染以前,咱們可使用getInitalState來指定數據的初始化值,使用componentDidMount來進行ajax請求,從服務器加載數據等操。代碼示例能夠參照react-webpack/src/components/Content.js

3. react-router

當頁面是組件構成的什麼,就自然的時候作單頁面應用,能夠在發生某種狀況下替換掉組件就能夠呈現不一樣的內容了。在講react-router使用以前,讓咱們先看看路由實現的一個大致的原理。
一個url通常由這幾個部分組成:協議、域名、端口、文件路徑、文件名、查詢條件與hash值,hash值的變化不會使頁面進行更新,基於此原理,能夠實現頁面路由,其過程通常以下:

  • 獲取hash的取值狀況
  • 給每種hash值註冊一個回調函數
  • 利用window.haschange()來監聽hash值得變化,並執行相應的回調函數,實現頁面的路由。(代碼來自http://web.jobbole.com/86407/)
function Router() {
  this.routes = {};
  this.currentUrl = '';
}
Router.prototype.route = function(path, callback) {
  this.routes[path] = callback || function(){};
};
Router.prototype.refresh = function() {
  this.currentUrl = location.hash.slice(1) || '/';
  this.routes[this.currentUrl]();
};
Router.prototype.init = function() {
  window.addEventListener('load', this.refresh.bind(this), false);
  window.addEventListener('hashchange', this.refresh.bind(this), false);
}
window.Router = new Router();
window.Router.init();

在html 5標準出現以前history對象的屬性與方法比較簡單,通常是使用history.back(),history.forward()實現頁面的前進與後退。可是在html5中爲其添加了新的方法與和一個事件,使其爲咱們實現頁面路由提供了新的方法。其中經常使用的方法有: history.pushState向當前瀏覽器的歷史堆棧中添加一個新的url; window.onpopstate會在瀏覽器進行前進後退的時候進行觸發。
react-router對兩種方式都有實現,咱們能夠選擇任意一種。其調用方式以下:

   <nav className="navbar navbar-inverse navbar-fixed-top" role="navigation">
            <ul  className='main-menu'>
                  <li><Link to="/">首頁</Link></li>
            //...       
            </ul>
   </nav>
   <Router history={browserHistory}>
        <Route path="/" component={Layout}>
            <IndexRoute component={Content}></IndexRoute>
          //...
        </Route>
  </Router>
相關文章
相關標籤/搜索