文档章节

學習 React.js : 概念和起步

开源中国匿名会员
 开源中国匿名会员
发布于 2015/04/15 00:07
字数 2108
阅读 2069
收藏 14
点赞 3
评论 8

Learning React.js: Getting Started and Concepts

By Ken Wheeler (@ken_wheeler)

#簡介

今天我們開始一個新系列的學習,學習 React,我們將集中在怎麼熟練並且有效的使用臉書的 React 庫上。在我們開始實際寫程序之前,還有更重要的一步,我們先講解一些基本概念,好了,我們開始吧。

##什麼是 React?

React 是臉書開發的一個 UI 庫,可以用來方便創建具有交互性,狀態性 & 重用性的 UI 組件。它已經被運用在了臉書的生產環境上了,並且 Instagram.com 也完全是用 React 來寫的。

它的一個獨一無二的買點是,它不僅能用在客戶端,還能在服務端渲染,並且可以配合著用。

它還有一個概念叫做虛擬DOM,它會基於狀態更新選擇性的進行渲染子節點。這使得你的組件通過最少的DOM操作保持更新。

##虛擬DOM是怎樣工作的?

想象一下,你有一個人類模型。它有一個人應該有的各種屬性,並且反映了這個人當前的狀態。React 差不多就是這樣對待 DOM 的。

現在再想一下,如果你讓這個對象發生一些改變,比如說加個小鬍子,然後再加點肌肉,再加雙 Steve Buscemi 那樣的眼睛。在 React 世界,當你做了這些更新之後,有兩件事情會發生。首先, React 執行"髒值檢查",確定發生了什麼改變。然後第二步是調和,把檢測到的更新結果反映到 DOM 上。

React 的方式,不會真的去再生一個小孩出來,重新把他們養大,而只是做個臉和手臂的整形。也就是說,如果你在輸入框裏面的文字發生改變,除非輸入框的父節點發生渲染,否則文字將會保持原狀。

由於 React 用的是假的 DOM 而不是真的那個,那麽這就讓有了一種新的可能。我們可以在服務端來渲染這個假的 DOM,然後,duang~服務端的 React View。

#開始

想要開始用 React 很簡單,只要去下載他們提供的 starter kit 就好:

React Starter Kit

你也可以叉他們提供的 JSFiddle:

React JSFiddle

##頁面設置

那麽我們來設置頁面,你需要導入 react.jsJSXTransformer.js,然後用 script 開始寫你的組件,記得把這個節點的 type 設置為 text/jsx

<!-- lang: js -->
<!DOCTYPE html>
<html>
  <head>
    <script src="build/react.js"></script>
    <script src="build/JSXTransformer.js"></script>
  </head>
  <body>
    <div id="mount-point"></div>
    <script type="text/jsx">
      // React Code Goes Here
    </script>
  </body>
</html>

在 React 裏面,組件必須加載到一個元素上,所以在例子裏面,我們可以用 div mount-point 來作為它的父容器。

當然這只是一個最簡單的起點,黨你實際上要寫點什麼的時候,最好用 Browerify 或者 webpack 這樣的工具來把你的組件拆分到不同的文件中。

#基礎

React 的基本單元模塊叫做組件(component),讓我們來寫一個:

<!-- lang: js -->
<script type="text/jsx">
    /** @jsx React.DOM */
    React.renderComponent(
        <h1>Hello, world!</h1>,
        document.getElementById('myDiv')
    );
</script>

如果你沒看之前的代碼,那你肯定一頭霧水不知道這個 javascript/HTML 到底做了什麼。

##JSX

這就是所謂的 JSX,它是一種 Javascript XML 語法轉換,可以讓你在你的 Javascript 裏面寫 類HTML。我之所以說 類HTML 是有多重含義。你僅僅是基於一個關聯對象來寫 XML 。

對於正常的 html 標籤,在 JSX 中,class 屬性變成了 className,而 for 則變成了 htmlFor,這是因為有些 Javascript 的保留字。你可以看這裏來瞭解更多的不同。

如果你不用 JSX,那麽這裏是不用它的一個版本:

<!-- lang: js -->
/** @jsx React.DOM */
React.renderComponent(
  React.DOM.h1(null, 'Hello, world!'),
  document.getElementById('myDiv')
);

如果你願意,你可以看這裏,來瞭解更多支持的元素。

在你的第一個代碼片段裏面,你有沒有注意到在頂行的 /** @jsx React.DOM */ ?它非常重要,它告訴 React 我們用了 JSX 所以這段代碼需要轉換,所以你用 JSX 語法的時候,你需要把它包含進來。

##組件

黨使用上面的 renderComponent 方法,第一個參數是我們希望渲染的組件,第二個參數是將要掛載上去的DOM 節點。我們可以用 createClass 方法來創建自定義組件類。它可以使用對象作為參數。下面讓我們來創建一個:

<!-- lang: js -->
var MyComponent = React.createClass({
    render: function(){
        return (
            <h1>Hello, world!</h1>
        );
    }
});

創建一個類之後,我們可以在 document 中像這樣渲染它:

<!-- lang: js -->
React.renderComponent(
    <MyComponent/>,
    document.getElementById('myDiv')
);

屌不屌,嗯哼?

##Props

當我們使用我們定義的組件的時候,我們可以添加屬性,叫做 props,這些屬性在我們的組件仲可以通過 this.props 調用並且可以在我們的渲染方法裏面動態渲染數據:

<!-- lang: js -->
var MyComponent = React.createClass({
    render: function(){
        return (
            <h1>Hello, {this.props.name}!</h1>
        );
    }
});

React.renderComponent(<MyComponent name="Handsome" />, document.getElementById('myDiv'));

##Specs,生命週期 & 狀態

render 方法是創建組件唯一需要進行測試的部分,不過這裏有一些生命週期相關方法和測試我們可以用到,當我們在實際的組件中應該會有所幫助。

###生命週期方法

  • componentWillMout 執行一次,在客戶端和服務端將要執行渲染的時候
  • componentDidMount 執行一次,只在客戶端,當渲染完成之後
  • shouldComponentUpdate 返回值判定組件是否需要更新的
  • componentWillUnmount 在卸載之前執行

###Specs

  • getInitialState 返回狀態初期值
  • getDefaultProps 設置退避 props 值,如果 沒有可用 props
  • mixins 一個對象數組,用來擴展當前組件的功能

###State

每個組件都有一個 state 對象和一個 props 對象。State 通過 setState 來設置。調用 setState 會觸發 UI 更新,它是 React 交互的基礎。如果我們想在所有交互開始之前設置一個初始狀態,我們可以用 getInitialState 方法。下面,讓我們看看我們是如何設置組件的狀態的:

<!-- lang: js -->
var MyComponent = React.createClass({
    getInitialState: function(){
        return {
            count: 5
        }
    },
    render: function(){
        return (
            <h1>{this.state.count}</h1>
        )
    }
});

##事件

React 還有一個內建跨瀏覽器事件系統。這些事件可以作為組件的屬性來追加也可以觸發方法。讓我們來通過事件來創建一個計數器:

<!-- lang: html -->
<div id="mount-point"></div>

<!-- lang: js -->
/** @jsx React.DOM */

var Counter = React.createClass({
  incrementCount: function(){
    this.setState({
      count: this.state.count + 1
    });
  },
  getInitialState: function(){
     return {
       count: 0
     }
  },
  render: function(){
    return (
      <div class="my-component">
        <h1>Count: {this.state.count}</h1>
        <button type="button" onClick={this.incrementCount}>Increment</button>
      </div>
    );
  }
});

React.renderComponent(<Counter/>, document.getElementById('mount-point'));

<!-- lang: css -->
body { 
  background: #bdc3c7;
  padding: 40px; 
}
.counter {
  width: 300px;
  margin: auto;
  background: #9b59b6;
  color: white;
  padding: 20px;
  text-align: center;
  h1 {
    margin: 0;
    padding: 20px;
    font-size: 36px;
  }
  button {
    background: #f1c40f;
    border: 0;
    box-shadow: 0px 5px 0px darken(#f1c40f, 20%);
    padding: 20px;
    width: 100%;
    outline: none;
    border-radius: 3px;
    color: darken(#8e44ad, 10%);
    font-weight: bold;
  }
}

##單向數據流

在 React 中,英勇的數據通過 state 和 props 對象單向傳播,和其他的雙向綁定的庫完全不一樣,比如說 Angular。意思也就是說,在多組件模式下,一個共通父組件將負責管理狀態以及將它通過 props 向下傳播。

如果需要,你的狀態可以通過使用 setState 方法來更新,以確保 UI 的刷新被執行。結果值會被傳播到子組件,通過使用屬性。也就是說子組件可以用 this.props 來訪問的那些。

下面用一個例子來解釋這些概念:

<!-- lang: js -->
/** @jsx React.DOM */
var FilteredList = React.createClass({
  filterList: function(event){
    var updatedList = this.state.initialItems;
    updatedList = updatedList.filter(function(item){
      return item.toLowerCase().search(
        event.target.value.toLowerCase()) !== -1;
    });
    this.setState({items: updatedList});
  },
  getInitialState: function(){
     return {
       initialItems: [
         "Apples",
         "Broccoli",
         "Chicken",
         "Duck",
         "Eggs",
         "Fish",
         "Granola",
         "Hash Browns"
       ],
       items: []
     }
  },
  componentWillMount: function(){
    this.setState({items: this.state.initialItems})
  },
  render: function(){
    return (
      <div className="filter-list">
        <input type="text" placeholder="Search" onChange={this.filterList}/>
      <List items={this.state.items}/>
      </div>
    );
  }
});

var List = React.createClass({
  render: function(){
    return (
      <ul>
      {
        this.props.items.map(function(item) {
          return <li key={item}>{item}</li>
        })
       }
      </ul>
    )  
  }
});

React.renderComponent(<FilteredList/>, document.getElementById('mount-point'));

<!-- lang: html -->
<div id="mount-point"></div>

<!-- lang: css -->
* {
  box-sizing: border-box;
}

body {
  padding: 20px;
  background: #2c3e50;
}

.filter-list {
  margin: auto;
  width: 300px;
  background: #3498db;
  border-radius: 5px;
  border: 1px solid darken(#3498db, 20%);
  input {
    width: 100%;
    display: block;
    padding: 10px;
    border-radius: 5px 5px 0px 0px;
    border: 0;
    font-size: 24px;
    &:focus {
      outline: none;
    }
  }
  ul {
    margin: 0;
    padding: 0;
    li {
      list-style-type: none;
      margin: 0;
      color: white;
      padding: 10px 20px;
      border-top: 1px solid darken(#3498db, 20%);
      &:hover {
        background: #2980b9;
      }
    }
  }
}

#總結

我們已經介紹了一些 React 的基礎知識了,花點時間去看看 React API 和學一下 JSX

在學習 React 的下一張,我們將結合 Express 來創建一個在服務端渲染的應用,就像在客戶端一樣,然後使用 socket.io 來保持兩邊同步。

敬請期待!

© 著作权归作者所有

共有 人打赏支持
开源中国匿名会员
粉丝 78
博文 104
码字总数 113453
作品 2
徐汇
技术主管
加载中

评论(8)

开源中国匿名会员
开源中国匿名会员

引用来自“开源中国匿名会员”的评论

來來來,道友們,我還需要12個同學來幫我註冊這個:https://koding.com/R/ilivebox

引用来自“Nixus”的评论

還有一個問題:既然這個是用來做APP的,能否介紹或者詳細講講在iOS和android上的如何測試? 謝謝!

引用来自“开源中国匿名会员”的评论

這個不是用來做APP的啊,只是一個 online IDE。我懶得到處同步代碼。

引用来自“Nixus”的评论

有人介绍说Facebook Groups就是用这个做的,我下载安装了,是一个APP
哦,我看你引用的是我貼的 koding 推廣地址。我以為你問的是 koding。 看起來你是剛開始學,不如這樣,你先去官網瞭解一下,什麼是源碼什麼是App。 然後再決定從哪裡開始學。 原文也說了,這教程是假設你有一定的編程水平的。所以……我覺得我似乎幫不上忙。
加班再加班
加班再加班

引用来自“开源中国匿名会员”的评论

來來來,道友們,我還需要12個同學來幫我註冊這個:https://koding.com/R/ilivebox

引用来自“Nixus”的评论

還有一個問題:既然這個是用來做APP的,能否介紹或者詳細講講在iOS和android上的如何測試? 謝謝!

引用来自“开源中国匿名会员”的评论

這個不是用來做APP的啊,只是一個 online IDE。我懶得到處同步代碼。
有人介绍说Facebook Groups就是用这个做的,我下载安装了,是一个APP
加班再加班
加班再加班

引用来自“开源中国匿名会员”的评论

來來來,道友們,我還需要12個同學來幫我註冊這個:https://koding.com/R/ilivebox

引用来自“Nixus”的评论

還有一個問題:既然這個是用來做APP的,能否介紹或者詳細講講在iOS和android上的如何測試? 謝謝!

引用来自“开源中国匿名会员”的评论

這個不是用來做APP的啊,只是一個 online IDE。我懶得到處同步代碼。
在线IDE,什么意思?这个和APP的差异有多大?
开源中国匿名会员
开源中国匿名会员

引用来自“开源中国匿名会员”的评论

來來來,道友們,我還需要12個同學來幫我註冊這個:https://koding.com/R/ilivebox

引用来自“Nixus”的评论

還有一個問題:既然這個是用來做APP的,能否介紹或者詳細講講在iOS和android上的如何測試? 謝謝!
這個不是用來做APP的啊,只是一個 online IDE。我懶得到處同步代碼。
开源中国匿名会员
开源中国匿名会员

引用来自“开源中国匿名会员”的评论

來來來,道友們,我還需要12個同學來幫我註冊這個:https://koding.com/R/ilivebox

引用来自“Nixus”的评论

博主,感覺有點兒問題,基礎 中的代碼,瀏覽器中執行報錯,未定義的函數React.renderComponent
這個在第三篇的時候,原文告訴我們,React 升級 .12 版本的時候已經把 renderComponent 改成了 render。所以最好比較一下官方文檔來學習。要不然有很多過期方法。React 還不穩定。
加班再加班
加班再加班

引用来自“开源中国匿名会员”的评论

來來來,道友們,我還需要12個同學來幫我註冊這個:https://koding.com/R/ilivebox
還有一個問題:既然這個是用來做APP的,能否介紹或者詳細講講在iOS和android上的如何測試? 謝謝!
加班再加班
加班再加班

引用来自“开源中国匿名会员”的评论

來來來,道友們,我還需要12個同學來幫我註冊這個:https://koding.com/R/ilivebox
博主,感覺有點兒問題,基礎 中的代碼,瀏覽器中執行報錯,未定義的函數React.renderComponent
开源中国匿名会员
开源中国匿名会员
來來來,道友們,我還需要12個同學來幫我註冊這個:https://koding.com/R/ilivebox
ASIO学习笔记

一、不似半桶水的大陆人,台湾人写的,十一个专题,循序渐进,非常细腻,很好理解;他把有关ioservice/ioservice::work等关键概念的缘由点明了。访问 http://dorgonman.net76.net/blog/?s=A...

雅各宾 ⋅ 2014/07/01 ⋅ 0

[转]做好大人的學習筆記:如何開始建立你的技能系統?

去年年初,我分享了自已的讀書筆記方法、開會筆記範本,而在今年的初始,我想來分享自己的「學習筆記」。 所謂學習筆記,可以是學習一個知識、學習一種技能、學習一項興趣,例如聽一系列演講...

yaotingxi ⋅ 2016/01/07 ⋅ 0

鳥哥的專訪

無心插柳的Linux學習者代言人 文/張智鴻 (記者) 2005-09-20

水幕青辰 ⋅ 2017/01/23 ⋅ 0

我什麼時候可以學習其他編程語言?

大家好我學習Python大約有1年的,我可以學習其他的語言嗎?可能是Java或C C + +。因為Python在香港的就業機會似乎不大。 但我真的很喜歡在python python和我還是新手,所以我不知道應不應該學...

jacklam ⋅ 2013/07/25 ⋅ 15

學習 React.js:用 React.js 和 Flux 創建一個簡單的購物車

[Creating A Simple Shopping Cart with React.js and Flux][1] Ken Wheeler (@ken_wheeler) 簡介 歡迎來到學習 React 的第四章這也是最後一章!到現在,我們已經學習了怎樣利用 React 的 AP...

开源中国匿名会员 ⋅ 2015/04/20 ⋅ 10

OSChina 技术周刊第三十期 —— IT 公司开源软件整理计划

每周技术抢先看,总有你想要的! 移动开发 【翻译】Intel® INDE for Google Android Studio 【软件】移动应用开发框架 Samurai-Native 【博客】學習 React.js:用 Node 和 React.js 創建一個...

OSC编辑部 ⋅ 2015/04/19 ⋅ 9

Eclipse - ERMaster 介紹與相關參考

(ERMaster 的畫面圖) 在進行前本篇時, 您可能必須被要求下列的知識領域: 對 DBMS 有初步的概念與操作 取得與安裝 Eclipse 3.4 IDE介面及 JDK API說明中文化教學 (老魚的舊文) API 的中文非必...

鉴客 ⋅ 2012/05/27 ⋅ 1

【开源访谈】Python China 创始人 Hsiaoming Yang 访谈实录

【嘉宾简介】 Hsiaoming Yang,Python china创始人,GitHub 上最活跃的国内开发者之一,常用 ID:lepture。 【正文】 1、请简单地介绍一下你自己(技术背景、学习经历、工作经历)。 我叫 Hs...

孔小菜 ⋅ 2015/06/01 ⋅ 16

android-opencc,中文简繁转换项目 OpenCC 的安卓版

android-opencc基于OpenCC的源代码,通过Android NDK编译并使用JNI调用OpenCC的中文简繁转换。它拥有OpenCC的最新词库,并支持以下转换。 HK2S, Traditional Chinese (Hong Kong Standard) t...

qichuan ⋅ 2016/05/12 ⋅ 3

中文Python--zhpy

周蟒(zhpy)是一套基於 python 程式語言 的 python 中文程程式語言模組, 在一般情況下, 周蟒讓你可以使用純中文句子(繁體或簡體)來編寫 Python 語言程式。 Python 是高階的, 即譯式的, 物件導...

匿名 ⋅ 2010/03/02 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Centos7重置Mysql 8.0.1 root 密码

问题产生背景: 安装完 最新版的 mysql8.0.1后忘记了密码,向重置root密码;找了网上好多资料都不尽相同,根据自己的问题总结如下: 第一步:修改配置文件免密码登录mysql vim /etc/my.cnf 1...

豆花饭烧土豆 ⋅ 今天 ⋅ 0

熊掌号收录比例对于网站原创数据排名的影响[图]

从去年下半年开始,我在写博客了,因为我觉得业余写写博客也还是很不错的,但是从2017年下半年开始,百度已经推出了原创保护功能和熊掌号平台,为此,我也提交了不少以前的老数据,而这些历史...

原创小博客 ⋅ 今天 ⋅ 0

LVM讲解、磁盘故障小案例

LVM LVM就是动态卷管理,可以将多个硬盘和硬盘分区做成一个逻辑卷,并把这个逻辑卷作为一个整体来统一管理,动态对分区进行扩缩空间大小,安全快捷方便管理。 1.新建分区,更改类型为8e 即L...

蛋黄Yolks ⋅ 今天 ⋅ 0

Hadoop Yarn调度器的选择和使用

一、引言 Yarn在Hadoop的生态系统中担任了资源管理和任务调度的角色。在讨论其构造器之前先简单了解一下Yarn的架构。 上图是Yarn的基本架构,其中ResourceManager是整个架构的核心组件,它负...

p柯西 ⋅ 今天 ⋅ 0

uWSGI + Django @ Ubuntu

创建 Django App Project 创建后, 可以看到路径下有一个wsgi.py的问题 uWSGI运行 直接命令行运行 利用如下命令, 可直接访问 uwsgi --http :8080 --wsgi-file dj/wsgi.py 配置文件 & 运行 [u...

袁祾 ⋅ 今天 ⋅ 0

JVM堆的理解

在JVM中,我们经常提到的就是堆了,堆确实很重要,其实,除了堆之外,还有几个重要的模块,看下图: 大 多数情况下,我们并不需要关心JVM的底层,但是如果了解它的话,对于我们系统调优是非常...

不羁之后 ⋅ 昨天 ⋅ 0

推荐:并发情况下:Java HashMap 形成死循环的原因

在淘宝内网里看到同事发了贴说了一个CPU被100%的线上故障,并且这个事发生了很多次,原因是在Java语言在并发情况下使用HashMap造成Race Condition,从而导致死循环。这个事情我4、5年前也经历...

码代码的小司机 ⋅ 昨天 ⋅ 2

聊聊spring cloud gateway的RetryGatewayFilter

序 本文主要研究一下spring cloud gateway的RetryGatewayFilter GatewayAutoConfiguration spring-cloud-gateway-core-2.0.0.RC2-sources.jar!/org/springframework/cloud/gateway/config/G......

go4it ⋅ 昨天 ⋅ 0

创建新用户和授予MySQL中的权限教程

导读 MySQL是一个开源数据库管理软件,可帮助用户存储,组织和以后检索数据。 它有多种选项来授予特定用户在表和数据库中的细微的权限 - 本教程将简要介绍一些选项。 如何创建新用户 在MySQL...

问题终结者 ⋅ 昨天 ⋅ 0

android -------- 颜色的半透明效果配置

最近有朋友问我 Android 背景颜色的半透明效果配置,我网上看资料,总结了一下, 开发中也是常常遇到的,所以来写篇博客 常用的颜色值格式有: RGB ARGB RRGGBB AARRGGBB 这4种 透明度 透明度...

切切歆语 ⋅ 昨天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部