認識React

認識React

準備

babel-cli

寫 React 有兩種方式:css

  • 經過 jsxhtml

  • 經過 jsnode

jsx 寫起來感受會更方便,但就須要用babel進行編譯了。react

用babel編譯 React 的 jsx 有三種方法( 關於 babel 的具體使用方法好像仍是有不少疑問的。之後會再折騰下)git

  • CLI工具編譯github

  • Node.js運行時編譯ajax

  • 瀏覽器(客戶端)運行時編譯npm

這樣我打算用 babel-cli 進行實時編譯,會比較方便。json

安裝

將工具全局安裝了:redux

$ [sudo] npm i -gd babel-cli

插件單獨安裝:

$ npm i -d babel-preset-react

使用

ps:我這裏以前說錯了

這裏有個坑,在 windows 系統的話,能夠直接babel --presets react,但在 os x 會報錯,要直接直接指定絕對路徑/usr/local/lib/node_modules/babel-preset-react

babel-cli 的 --presets 參數是會向父級目錄尋找 node_module 裏面的 babel-prest-xxx 插件,若是沒有找到,就會相對於當前目錄路徑尋找插件。

除此以外,你也能夠寫成絕對路徑的插件地址。

在單獨安裝了插件後,你就能夠不用寫絕對路徑地址了。

$ babel --presets react jsx --watch --out-dir build

若是不想每次敲命令,能夠在項目目錄(就是敲babel命令的目錄)中新建一個.babelrc文件:

{
    "presets": ["react"]
}

這樣敲命令的時候就能夠不要帶上--presets參數了。

$ babel jsx --watch --out-dir build

jsx是須要編譯的文件夾,build是編譯後產出的文件夾。

使用 React v0.14.x

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>
<body>
  <div id="JBody"></div>
 
  <!-- react 核心 js-->
  <script src="http://cdnjs.cloudflare.com/ajax/libs/react/0.14.8/react.min.js"></script>
  <script src="http://cdnjs.cloudflare.com/ajax/libs/react/0.14.8/react-dom.min.js"></script>
  
  <!-- 編譯後的 jsx 引用 -->
  <script src="./build/test.js"></script>
</body>
</html>

ps:官網的示例中,react 核心 js 是放在 <head></head> 標籤裏面的,由於這樣的話,在最後渲染 DOM 的時候就能夠直接選擇在<body></body>標籤裏面了。否則就要像我這樣,在<body></body>標籤裏面給個節點供 react 進行渲染。

組件

組件概念

先來個 Input 組件。

var Input = React.createClass({
  render: function(){
    return(
      <label for={this.props.id}>
        <i>四月是誰的謊話</i>
        <input id={this.props.id} value type="text"/>
      </label>
    )
  }
})

經過 Reac.createClass 建立的就是組件了。
rander 函數 return 的東西能夠稱做模板。
每一個組件都是一個樹形結構(有父級節點和子節點,也就是不能同時存在兩個頂級節點,react 是不容許的)。
在 React 裏面就是一個個組件組成的,組合在一塊兒就也是一個樹形結構。

組件的渲染

ReactDOM.render(
  <Input />,
  document.getElementById('JBody')
);

調用 ReactDOM.render 方法進行渲染,第一個參數是組件了,第二個是裝載該組件的容器。
一樣的,第一個參數只支持樹形結構,也就是隻有一個頂級節點。

組件的兩個重要對象

props

props 就是一個組件模板的數據對象。裏面儲存着靜態的數據,也就是隻在調用時賦值,以後若是有數據的改變也不會再次進行模板的渲染了。

props 的使用:

var Input = React.createClass({
  render: function(){
    return(
      // 使用 props
      <label for={this.props.iid}>
        <i>四月是誰的謊話</i>
        <input id={this.props.iid} value type="text"/>
      </label>
    )
  }
})

ReactDOM.render(
  <Input iid="JWho"/>, // 賦值 props
  document.getElementById('JBody')
)

state

stateprops 是相對的。
state 是動態的數據對象,也就是能夠任什麼時候候進行賦值,以後若是有數據的改變會進行模板的再次渲染(這裏渲染的話就涉及到了 react 的 virtual DOM)了。

state 的使用:
這裏定義個列表組件Items

var Items = React.createClass({
  getInitialState: function() {
    return {
      data: [12312,1231,45,51512312,2131]
    }
  },
  render: function(){
    return(
      <ul>
        {this.state.data.map((value,i) => {
          return <li>{value}</li>
        })}
      </ul>
    )
  }
})

getInitialState 用來定義 state 的初始數據。

還能夠在組件的生命週期函數裏能夠從服務器獲取數據而後經過調用 this.setState 方法進行對 state 賦值。

this.setState 就是那個 能夠任什麼時候候進行賦值 的方法了。

改造下 Input 組件,state示例:

var Input = React.createClass({
  getInitialState: function() {
    return {
      who: '我'
    }
  },
  change: function(e){
    let target = e.target
    this.setState({
      who : target.value
    })
  },
  render: function(){
    // 使用 props
    return(
      <div>
        <label for={this.props.iid}>
          <i>四月是誰的謊話?</i>
          <input id={this.props.iid} onChange={this.change} type="text"/>
        </label>
        <p>{`四月是${this.state.who}的謊話`}</p>
      </div>
    )
  }
})

ReactDOM.render(
  <Input />,
  document.getElementById('JBody')
)

這裏進行了事件 onChange 的調用,當觸發 change 事件的時候,state 就會進行改版了。
關於時間系統的文檔:

組件的文檔

組件的通訊

react 的核心中是沒有關於兩個不一樣組件之間的相互通訊的方法的,可是官方給出了一種flux的通訊概念flux中文文檔,然而社區彷佛並不以爲這一套方案很好用,因而有了另外一種通訊概念redux

我對通訊的理解

react 的組件化概念是很明確的,但對於組件之間通訊能夠說是基本沒有。

在個人理解裏面,組件的通訊能夠更明確地理解爲數據的通訊,由於數據和組件渲染分離是很重要的。
一個負責不一樣組件渲染的組件容器,會自行判斷數據的狀態從而進行最終組件的渲染。這樣就能作到數據和組件渲染的分離了。這個概念就是Container Components
Leveling Up With React: Container Components

在其餘的一些mv*框架裏面,每一個組件都有本身的通訊接口,從而能夠在A組件裏面跟B組件進行數據通訊,但 react 倒是沒有這樣的接口,從而咱們就須要一個藉助一些通訊工具,好比手機、電腦什麼的。

沒錯,咱們能夠把 Flux、Redux 這些工具當成通訊工具來看待,若是你喜歡,你徹底能夠用寫信的方式(本身寫一個觀察者模式的函數)。當A組件的數據要與B組件的數據進行打電話的時候,撥通B組件的電話號碼,而後把數據告訴B組件就能夠了。數據會在運營商的系統裏面走一遭,而後傳到B組件那裏的。

通訊場景

例如登陸。

在一個頁面上,若是存在兩個或兩個以上須要獲取登陸信息的組件,就將須要進行通訊了。
當一個組件進行了登陸以後,應該通知其餘須要更新登陸信息的組件。這樣就產生了通訊的需求了。

組件的抽象與封裝

這塊到沒有太多的實踐,組件的拆分、定義是一門深思熟慮的藝術。等有實踐經驗找到門路以後再作補充。
但這塊多是不少人會忽略的,優秀的抽象封裝首先應該是針對方便開發和維護的,其次纔是複用。

github:https://github.com/jincdream/jincdream.g...

相關文章
相關標籤/搜索