編輯:關於Android編程
在學習React之前,需要具備一下基礎知識:
- HTML5
- CSS
- JavaScript
<script type="text/babel"> ReactDOM.render(
<script src="build/react.js"></script> <script src="build/react-dom.js"></script> <script src="https://unpkg.com/[email protected]/browser.min.js"></script>
使用實例:
輸出Hello, world!
實例解析:
實例中我們引入了三個庫: react.js 、react-dom.js 和 browser.min.js:
- react.js - React 的核心庫
- react-dom.js - 提供與 DOM 相關的功能
- browser.min.js - 用於將 JSX 語法轉為 JavaScript 語法
ReactDOM.render(
以上代碼將一個 h1 標題,插入 id=”example” 節點中。
注意:如果我們需要使用 JSX,則 script標簽的 type 屬性需要設置為 text/babel
我們建議在 React 中使用 CommonJS 模塊系統,比如 browserify 或 webpack,本教程使用 webpack。
$ npm install babel -g $ npm install webpack -g $ npm install webpack-dev-server -g
創建一個根目錄,名稱為mazouriApp,再使用npm init初始化,生成package.json文件:
因為我們要使用React,所以我們需要先安裝它, –save命令用於將包添加至package.json文件
npm install react --save npm install react-dom --save
同時我們也需要安裝一些babel插件
npm install babel-core npm install babel-loader npm install babel-preset-react npm install babel-preset-es2015
接下來我們創建一些必要的文件:
touch index.html touch App.jsx touch main.js touch webpack.config.js
打開webpack.config.js 文件添加以下代碼:
var config = { entry: './main.js', outout: { path: './', filename: 'index.js', }, devServer: { inline: true, port: 7777 }, module: { loaders: [{ test: /\.jsx?$/, exclude: /node_moudules/, loader: 'babel-loader', query: { presets: ['es2015', 'react'] } }] } } module.exports = config;entry: 指定打包的入口文件main.js output: 配置打包結果,path定義了輸出的文件夾,filename則定義了打包結果文件的名稱 devServer: 設置服務器端口號為7777,端口號你可以自己設定 module: 定義了對模塊的處理邏輯,這裡可以用loaders定義一些列的加載器,以及一些正則。當需要加載的文件匹配test的正則時,就會調用後面的loader對文件進行處理,這正是webpack強大的原因
現在打開 package.json 文件,找到 “scripts” 中的 “test” “echo \”Error: no test specified\” && exit 1” 使用以下代碼替換:
"start": "webpack-dev-server --hot"
替換後的 package.json 文件 內容如下:
{ "name": "mazouri-react-demo", "version": "1.0.0", "description": "我的react demo", "main": "index.js", "scripts": { "start": "webpack-dev-server --hot" }, "author": "", "license": "ISC", "dependencies": { "react": "^15.3.1", "react-dom": "^15.3.1" } }
現在我們可以使用 npm start 命令來啟動服務。–hot 命令會在文件變化後重新載入,這樣我們就不需要在代碼修改後重新刷新浏覽器就能看到變化。
設置 div id = “app” 為我們應用的根元素,並引入 index.js 腳本文件
這是第一個 react 組件,這個組件將輸出 Hello World!!!。
import React from 'react'; class App extends React.Component { render() { return (Hello World!!!
我們需要引入組件並將其渲染到根元素 App 上,這樣我們才可以在浏覽器上看到它
import React from 'react'; import ReactDOM from 'react-dom'; import App from './App.jsx'; ReactDOM.render(, document.getElementById('app'))
如果想要組件可以在任何的應用中使用,需要在創建後使用 export 將其導出,在使用組件的文件使用 import 將其導入。
完成以上配置後,我們即可運行該服務:
$ npm start
React 使用JSX來代替常規的JavaScript。
JSX是一個看起來很像XML的JavaScript語法擴展。
我們不需要一定使用JSX,但它有以下優點:
JSX看起來類似HTML,我們可以看下實例:
ReactDOM.render(
我們可以在上面代碼中嵌套多個HTML標簽,需要使用一個div元素包裹它,實例中的p元素添加了自定義屬性data-myattribute,添加自定義屬性需要使用data-前綴。
ReactDOM.render(
這是一個段落
, document.getElementById('example') );你的React JSX 代碼可以放在一個獨立文件上,例如我們創建一個helloworld_react.js文件,代碼如下:
ReactDOM.render(
然後在 HTML 文件中引入該 JS 文件:
<script type="text/babel" src="helloworld_react.js"></script>
我們可以在 JSX 中使用 JavaScript 表達式。表達式寫在花括號 {} 中。實例如下:
ReactDOM.render(
在 JSX 中不能使用 if else 語句,但可以使用 conditional (三元運算) 表達式來替代。以下實例中如果變量 i 等於 1 浏覽器將輸出 true, 如果修改 i 的值,則會輸出 false.
ReactDOM.render(
React 推薦使用內聯樣式。我們可以使用 camelCase 語法來設置內聯樣式. React 會在指定元素數字後自動添加 px 。以下實例演示了為 h1 元素添加 myStyle 內聯樣式:
var myStyle = { fontSize: 100, color: '#FF0000' }; ReactDOM.render(
注釋需要寫在花括號中,實例如下:
ReactDOM.render(
JSX 允許在模板中插入數組,數組會自動展開所有成員:
var arr = [
React 可以渲染 HTML 標簽 (strings) 或 React 組件 (classes)。
要渲染 HTML 標簽,只需在 JSX 裡使用小寫字母的標簽名。
var myDivElement =; ReactDOM.render(myDivElement, document.getElementById('example'));
要渲染 React 組件,只需創建一個大寫字母開頭的本地變量。
var MyComponent = React.createClass({/*...*/}); var myElement =; ReactDOM.render(myElement, document.getElementById('example'));
React 的 JSX 使用大、小寫的約定來區分本地組件的類和 HTML 標簽。
注意:由於 JSX 就是 JavaScript,一些標識符像 class 和 for 不建議作為 XML 屬性名。作為替代,React DOM 使用 className 和 htmlFor 來做對應的屬性。
這節我們討論如何使用組件使得我們的應用更容易來管理。
接下來我們封裝一個輸出”Hello world!”的組件,組件名為HelloMessage:
var HelloMessage = React.createClass({ render: function() { return
實例解析:
React.createClass 方法用於生成一個組件類 HelloMessage。
實例組件類並輸出信息。
注意,原生 HTML 元素名以小寫字母開頭,而自定義的 React 類名以大寫字母開頭,比如 HelloMessage 不能寫成 helloMessage。除此之外還需要注意組件類只能包含一個頂層標簽,否則也會報錯。
如果我們需要向組件傳遞參數,可以使用 this.props 對象,實例如下:
var HelloMessage = React.createClass({ render: function() { return
以上實例中 name 屬性通過 this.props.name 來獲取.
注意,在添加屬性時, class 屬性需要寫成 className ,for 屬性需要寫成 htmlFor ,這是因為 class 和 for 是 JavaScript 的保留字。
我們可以通過創建多個組件來合成一個組件,即把組件的不同功能點進行分離。
以下實例我們實現了輸出網站名字和網址的組件:
var WebSite = React.createClass({ render: function() { return (
實例中 WebSite 組件使用了 Name 和 Link 組件來輸出對應的信息,也就是說 WebSite 擁有 Name 和 Link 的實例
React 把組件看成是一個狀態機(State Machines)。通過與用戶的交互,實現不同狀態,然後渲染 UI,讓用戶界面和數據保持一致。
React 裡,只需更新組件的 state,然後根據新的 state 重新渲染用戶界面(不要操作 DOM)。
以下實例中創建了 LikeButton 組件,getInitialState 方法用於定義初始狀態,也就是一個對象,這個對象可以通過 this.state 屬性讀取。當用戶點擊組件,導致狀態變化,this.setState 方法就修改狀態值,每次修改以後,自動調用 this.render 方法,再次渲染組件。
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 ? '喜歡' : '不喜歡'; return (
你{text}我。點我切換狀態。
); } }); React.render(state 和 props 主要的區別在於 props 是不可變的,而 state 可以根據與用戶交互來改變。這就是為什麼有些容器組件需要定義 state 來更新和修改數據。 而子組件只能通過 props 來傳遞數據
以下實例演示了如何在組件中使用 props:
var HelloMessage = React.createClass({ render: function() { return
實例中 name 屬性通過 this.props.name 來獲取。
你可以通過 getDefaultProps() 方法為 props 設置默認值,實例如下:
var HelloMessage = React.createClass({ getDefaultProps: function() { return { name: 'Runoob' }; }, render: function() { return
以下實例演示了如何在應用中組合使用 state 和 props 。我們可以在父組件中設置 state, 並通過在子組件上使用 props 將其傳遞到子組件上。在 render 函數中, 我們設置 name 和 site 來獲取父組件傳遞過來的數據
var WebSite = React.createClass({ getInitialState: function() { return { name: "Geek馬走日", site: "https://github.com/mazouri" }; }, render: function() { return (
Props 驗證使用 propTypes,它可以保證我們的應用組件被正確使用,React.PropTypes 提供很多驗證器 (validator) 來驗證傳入數據是否有效。當向 props 傳入無效數據時,JavaScript 控制台會拋出警告。
以下實例創建一個 Mytitle 組件,屬性 title 是必須的且是字符串,如果是一個數字則會報錯 :
var title = "React 初探"; // var title = 123; var MyTitle = React.createClass({ propTypes: { title: React.PropTypes.string.isRequired, }, render: function() { return
更多驗證器說明如下:
React.createClass({ propTypes: { // 可以聲明 prop 為指定的 JS 基本數據類型,默認情況,這些數據是可選的 optionalArray: React.PropTypes.array, optionalBool: React.PropTypes.bool, optionalFunc: React.PropTypes.func, optionalNumber: React.PropTypes.number, optionalObject: React.PropTypes.object, optionalString: React.PropTypes.string, // 可以被渲染的對象 numbers, strings, elements 或 array optionalNode: React.PropTypes.node, // React 元素 optionalElement: React.PropTypes.element, // 用 JS 的 instanceof 操作符聲明 prop 為類的實例。 optionalMessage: React.PropTypes.instanceOf(Message), // 用 enum 來限制 prop 只接受指定的值。 optionalEnum: React.PropTypes.oneOf(['News', 'Photos']), // 可以是多個對象類型中的一個 optionalUnion: React.PropTypes.oneOfType([ React.PropTypes.string, React.PropTypes.number, React.PropTypes.instanceOf(Message) ]), // 指定類型組成的數組 optionalArrayOf: React.PropTypes.arrayOf(React.PropTypes.number), // 指定類型的屬性構成的對象 optionalObjectOf: React.PropTypes.objectOf(React.PropTypes.number), // 特定 shape 參數的對象 optionalObjectWithShape: React.PropTypes.shape({ color: React.PropTypes.string, fontSize: React.PropTypes.number }), // 任意類型加上 `isRequired` 來使 prop 不可空。 requiredFunc: React.PropTypes.func.isRequired, // 不可空的任意類型 requiredAny: React.PropTypes.any.isRequired, // 自定義驗證器。如果驗證失敗需要返回一個 Error 對象。不要直接使用 `console.warn` 或拋異常,因為這樣 `oneOfType` 會失效。 customProp: function(props, propName, componentName) { if (!/matchme/.test(props[propName])) { return new Error('Validation failed!'); } } }, /* ... */ });
這節我們將討論 React 組件 API。我們將講解以下7個方法:
設置狀態:setState 替換狀態:replaceState 設置屬性:setProps 替換屬性:replaceProps 強制更新:forceUpdate 獲取DOM節點:findDOMNode 判斷組件掛載狀態:isMountedsetState(object nextState[, function callback])
參數說明
- nextState,將要設置的新狀態,該狀態會和當前的state合並
- callback,可選參數,回調函數。該函數會在setState設置成功,且組件重新渲染後調用
callback,可選參數,回調函數。該函數會在setState設置成功,且組件重新渲染後調用
不能在組件內部通過this.state修改狀態,因為該狀態會在調用setState()後被替換
setState()並不會立即改變this.state,而是創建一個即將處理的state。setState()並不一定是同步的,為了提升性能React會批量執行state和DOM渲染。
setState()總是會觸發一次組件重繪,除非在shouldComponentUpdate()中實現了一些條件渲染邏輯
var Counter = React.createClass({ getInitialState: function () { return { clickCount: 0 }; }, handleClick: function () { this.setState(function(state) { return {clickCount: state.clickCount + 1}; }); }, render: function () { return (
實例中通過點擊 h2 標簽來使得點擊計數器加 1
replaceState(object nextState[, function callback])nextState,將要設置的新狀態,該狀態會替換當前的state callback,可選參數,回調函數。該函數會在replaceState設置成功,且組件重新渲染後調用
setProps(object nextProps[, function callback])nextProps,將要設置的新屬性,該狀態會和當前的props合並 callback,可選參數,回調函數。該函數會在setProps設置成功,且組件重新渲染後調用
replaceProps(object nextProps[, function callback])nextProps,將要設置的新屬性,該屬性會替換當前的props callback,可選參數,回調函數。該函數會在replaceProps設置成功,且組件重新渲染後調用
forceUpdate([function callback])callback,可選參數,回調函數。該函數會在組件render()方法調用後調用
DOMElement findDOMNode()返回值:DOM元素DOMElement
bool isMounted()返回值:true或false,表示組件是否已掛載到DOM中
組件的生命周期可以分為三個狀態:
- Mounting:已插入真實 DOM
- Updating:正在被重新渲染
- Unmounting:已移出真實 DOM
生命周期的方法有:
- componentWillMount 在渲染前調用,在客戶端也在服務端
- componentDidMount : 在第一次渲染後調用,只在客戶端。之後組件已經生成了對應的DOM結構,可以通過this.getDOMNode()來進行訪問。 如果你想和其他JavaScript框架一起使用,可以在這個方法中調用setTimeout, setInterval或者發送AJAX請求等操作(防止異部操作阻塞UI)
- componentWillReceiveProps 在組件接收到一個新的prop時被調用。這個方法在初始化render時不會被調用
- shouldComponentUpdate 返回一個布爾值。在組件接收到新的props或者state時被調用。在初始化時或者使用forceUpdate時不被調用。 可以在你確認不需要更新組件時使用。
- componentWillUpdate在組件接收到新的props或者state但還沒有render時被調用。在初始化時不會被調用
- componentDidUpdate 在組件完成更新後立即調用。在初始化時不會被調用
- componentWillUnmount在組件從 DOM 中移除的時候立刻被調用
以下實例在 Hello 組件加載以後,通過 componentDidMount 方法設置一個定時器,每隔100毫秒重新設置組件的透明度,並重新渲染:
var Hello = React.createClass({ getInitialState: function () { return { opacity: 1.0 }; }, componentDidMount: function () { this.timer = setInterval(function () { var opacity = this.state.opacity; opacity -= .05; if (opacity < 0.1) { opacity = 1.0; } this.setState({ opacity: opacity }); }.bind(this), 100); }, render: function () { return (Hello {this.props.name} ); } }); ReactDOM.render(
以下實例初始化 state , setNewnumber 用於更新 state。所有生命周期在 Content 組件中
var Button = React.createClass({ getInitialState: function() { return { data:0 }; }, setNewNumber: function() { this.setState({data: this.state.data + 1}) }, render: function () { return ( ); } }) var Content = React.createClass({ componentWillMount:function() { console.log('Component WILL MOUNT!') }, componentDidMount:function() { console.log('Component DID MOUNT!') }, componentWillReceiveProps:function(newProps) { console.log('Component WILL RECIEVE PROPS!') }, shouldComponentUpdate:function(newProps, newState) { return true; }, componentWillUpdate:function(nextProps, nextState) { console.log('Component WILL UPDATE!'); }, componentDidUpdate:function(prevProps, prevState) { console.log('Component DID UPDATE!') }, componentWillUnmount:function() { console.log('Component WILL UNMOUNT!') }, render: function () { return (
React 組件的數據可以通過 componentDidMount 方法中的 Ajax 來獲取,當從服務端獲取數據庫可以將數據存儲在 state 中,再用 this.setState 方法重新渲染 UI.
當使用異步加載數據時,在組件卸載前使用 componentWillUnmount 來取消未完成的請求。
以下實例演示了獲取 Github 用戶最新 gist 共享描述:
var UserGist = React.createClass({ getInitialState: function() { return { username: '', lastGistUrl: '' }; }, componentDidMount: function() { this.serverRequest = $.get(this.props.source, function (result) { var lastGist = result[0]; this.setState({ username: lastGist.owner.login, lastGistUrl: lastGist.html_url }); }.bind(this)); }, componentWillUnmount: function() { this.serverRequest.abort(); }, render: function() { return (); } }); ReactDOM.render(
以上代碼使用 jQuery 完成 Ajax 請求。
在實例中我們設置了輸入框 input 值value = {this.state.data}。在輸入框值發生變化時我們可以更新 state。我們可以使用 onChange 事件來監聽 input 的變化,並修改 state
var HelloMessage = React.createClass({ getInitialState: function() { return {value: 'Hello Runoob!'}; }, handleChange: function(event) { this.setState({value: event.target.value}); }, render: function() { var value = this.state.value; return
上面的代碼將渲染出一個值為 Hello Runoob! 的 input 元素,並通過 onChange 事件響應更新用戶輸入的值
在以下實例中我麼將為大家演示如何在子組件上使用表單。 onChange 方法將觸發 state 的更新並將更新的值傳遞到子組件的輸入框的 value 上來重新渲染界面。
你需要在父組件通過創建事件句柄 (handleChange) ,並作為 prop (updateStateProp) 傳遞到你的子組件上。
var Content = React.createClass({ render: function() { return
以下實例演示通過 onClick 事件來修改數據:
var HelloMessage = React.createClass({ getInitialState: function() { return {value: 'Hello Runoob!'}; }, handleChange: function(event) { this.setState({value: '菜鳥教程'}) }, render: function() { var value = this.state.value; return
當你需要從子組件中更新父組件的 state 時,你需要在父組件通過創建事件句柄 (handleChange) ,並作為 prop (updateStateProp) 傳遞到你的子組件上。實例如下:
var Content = React.createClass({ render: function() { return
React 支持一種非常特殊的屬性 Ref ,你可以用來綁定到 render() 輸出的任何組件上。
這個特殊的屬性允許你引用 render() 返回的相應的支撐實例( backing instance )。這樣就可以確保在任何時間總是拿到正確的實例。
綁定一個 ref 屬性到 render 的返回值上:
在其它代碼中,通過 this.refs 獲取支撐實例:
var input = this.refs.myInput; var inputValue = input.value; var inputRect = input.getBoundingClientRect();
你可以通過使用 this 來獲取當前 React 組件,或使用 ref 來獲取組件的引用,實例如下:
var MyComponent = React.createClass({ handleClick: function() { // 使用原生的 DOM API 獲取焦點 this.refs.myInput.focus(); }, render: function() { // 當組件插入到 DOM 後,ref 屬性添加一個組件的引用於到 this.refs return (); } }); ReactDOM.render(
實例中,我們獲取了輸入框的支撐實例的引用,子點擊按鈕後輸入框獲取焦點。
我們也可以使用 getDOMNode()方法獲取DOM元素。
簽名安卓應用程序Android應用以它的包名作為唯一標識。如果在同一部手機上安裝兩個包名相同的應用,後面安裝的應用就會覆蓋前面安裝的應用。為了避免這種情況的發生,Andr
本文將介紹Android設備中的傳感器。傳感器概述(Sensors Overview)大部分Android設備內置了大量的傳感器,比較常見的有測量位移的、感應方向的、感應
活動的啟動模式啟動模式一共有四種,分別是 standard、singleTop、singleTask 和singleInstance,可以在AndroidManifest
今天整理之前的代碼,忽然看到之前自己寫的一個刮刮卡,整理下以便以後使用,同時分享給需要的朋友,如有錯誤,還請多多指正。實現的步驟,其實就是徒手畫三個圖層疊加在一起,最上層