ReactNative入門-React基礎

本節包含內容有

React背景及特點
創建React應用
開始第一個簡單程序 - 運行Hello World
JSX語法入門
組件
Props
state
組件的生命周期

React背景及特點

  • React背景介紹

    在Web應用開發的早期,構建Web應用的唯一方式就是向服務器發送請求,然后服務器響應請求并返回一個完整的頁面。從開發角度上講這種方式非常簡單,但是這種開發方式會造成很不好的用戶體驗,用戶的很多行為都需要向服務器請求,等待服務器的反應。因此,開發者開始開發各種類庫,使用JavaScript在瀏覽器端渲染應用。

    React起源于Facebook公司,期初用于Instagram網站開發。React是一個用于構建用戶界面的JavaScript庫,不是一個MVC框架,提出了一種新的開發模式和理念,它強調的是“用戶界面”。

  • React特點

    1.作為UI

    React可以作為MVC中的View層進行使用,并且在已有項目中很容易使用React開發新功能。
    2.虛擬DOM

    虛擬DOM是React最重要的特性,實現了優化視圖的渲染和刷新。以前沒有Ajax技術的時候,Web頁面從服務器端整體渲染出HTML,輸出到瀏覽器端進行渲染,同樣的,用戶的一個改變頁面的操作也會刷新整個頁面來完成。知道Ajax的出現,實現頁面局部刷新,帶來的高效和分離讓Web開發者們驚嘆不已。但隨之而來的問題是復雜的用戶交互及展現需要通過大量的DOM操作來完成,這讓頁面的性能以及開發的效率又出現了新的瓶頸。如何進行高性能的復雜DOM操作通常是衡量一個前端開發人員技能的重要指標。

    時至今日,談到前端性能優化,減少DOM元素,減少reflow和repaint,編碼過程盡量減少DOM的查詢等手段是大家耳熟能詳的。而頁面任何UI的變化都是通過整體刷新來完成的。而React之所以快,是因為它不直接操作DOM,而是引進虛擬DOM的實現來解決這個問題。

    3.組件化

    虛擬DOM(virtual-dom)不僅帶來了簡單UI開發邏輯,同時也帶來了組件化開發的思想。所謂組件,即封裝起來的具有獨立功能的UI部件。React推薦以組件的方式去重新思考UI構成,將UI上每一個功能相對獨立的模塊定義出呢個組件,然后將小的組件通過組合或者嵌套的方式構成的大的組件,最終完成整體UI的構建。

    如果說MVC的思想讓你做到視圖-數據-控制器的分離。那么組件化的思考方式則是帶來了UI功能模塊之間的分離。

    對于React而言,開發者從功能的角度出發,將UI分成不同的組件,每個組件都獨立封裝。在React中,你按照界面模塊自然劃分的方式來組織和編寫你的代碼。每個組件只關心自己部分的邏輯,彼此獨立。React組件應該具有如下特征:可組合、可重用、可維護

    4.數據流

    React實現了單向的數據流,相對于傳統的數據綁定,React更加靈活、便捷。

  • React學習準備

    1、前端基礎知識:HTML,CSS,JavaScript
    2、JSX語法
    3、ES6相關知識
    4、React中文網站:http://www.css88.com/react/index.html

  • React和ReactNative的關系

    React用于Web用用開發。ReactNative采用React方式進行移動應用開發。
    ReactNative采用React語法,用于進行JavaScript跨終端應用開發,既擁有原生Native的交互體驗,又能夠保留React自由的開發效率。使用靈活的HTML和CSS布局,使用React語法構建組件,然后同時運行在iOS和Android平臺上,“Learn once,write anywhere”

1.創建React應用

使用命令行:

npm install -g create-react-app
create-react-app my-app

在my-app目錄下運行npm

cd my-app
npm start

這時候在瀏覽器中就會顯示運行結果,可以在index.js文件下進行修改

整個文件目錄是

2.運行Hello World

import React from 'react';
import ReactDOM from 'react-dom';
import registerServiceWorker from './registerServiceWorker';
import './index.css';

// React的最基本方法,用于將模板轉換成HTML語言,渲染DOM并插入指定的DOM節點
/*
三個參數
第一個:模板的渲染內容(HTML形式)
第二個: 這段模板需要插入的DOM節點,本程序中id為root的div節點
第三個:渲染后的回調,一般不用
*/
ReactDOM.render(
    <h1>Hello World</h1>
    document.getElementById('root')
);

registerServiceWorker();

3.JSX入門

JSX不是一門新的語言,是個語法(語法糖)

  • JSX必須借助React環境運行
  • JSX標簽其實就是HTML標簽,只不過我們在JavaScript中書寫這些標簽的時候,不用使用“”括起來
<h1>Hello World</h1> 這就是JSX語法
  • 轉換:JSX語法能夠讓我們更直觀的看到組件的DOM結構,不能直接在瀏覽器上運行,最終會轉化成JavaScript代碼
// JSX語法書寫
ReactDOM.render(
    <h1>
       Hello React
    </h1>,
    document.getElementById('root')
);

// JavaScript語法書寫
ReactDOM.render(
    React.createElement("h1", null, "Hello React"),
    document.getElementById('root')
);

兩種寫法的比較,可以看出來JSX的寫法結構很清晰,書寫也簡單。

  • 如何在JSX中運行JavaScript代碼,使用{表達式}括起來,如下邊的寫法
var text = "世界"
ReactDOM.render(
    <h1>{text}</h1>,
    document.getElementById('root')
);
  • JSX語法在屬性、設置樣式和事件綁定等中的應用

4.組件

(1)定義組件
創建一個組件類,用于輸出Hello React

var HelloMessage = React.createClass({
    render: function () {
      // return <h1>Hello React</h1>;
       // 如果想動態輸出內容這里使用屬性
        return <h1>{this.props.helloText}</h1>
    }
});

ReactDOM.render(
    // 在模板中插入<HelloMessage />會自動生成一個實例
    <HelloMessage helloText="Hello React"/>,
    document.getElementById('root')
);
  • React中創建的組件類以大寫字母開頭,駝峰命名法
  • 在React中使用React.creatClass方法創建一個組件類
  • 核心代碼:每個組件都必須實現自己的render方法。輸出定義好的組件模板。返回值:null,false,組件模板
  • 注意:組件類只能包含一個頂層標簽

(2)組件的樣式
設置組件的樣式: 內聯樣式,對象樣式,選擇器樣式

注意:在React和HTML5中設置樣式時的書寫格式是由區別的:
1.HTML5以分號;結尾,React以逗號,結尾
2.HTML5中key、value都不加引號,React中屬于JavaScript對象,key的名字不能出現分隔符“-”,需要使用駝峰命名法,
如果value為字符串,需要加引號。
3.HTML5中,value如果是數字需要帶單位,React中不需要帶單位

定義一個組件類,同時使用三種設置組件樣式的方式。div使用內聯樣式:設置背景顏色,邊框大小,邊框顏色;h1使用對象樣式:設置背景顏色,字體顏色;p使用選擇器樣式:設置字體大小

var ShowMessage = React.createClass({
    render: function() {
        return (
            <div style={{backgroundColor:"yellow", borderWidth: 5, borderColor:"black", borderStyle:"solid"}}>
                <h1 style={hStyle}>{this.props.firstRow}</h1>
                // 在React中使用選擇器樣式設置組件樣式時,屬性名不能使用class,需要使用className替換。同樣的還有使用htmlFor替換for
                <p className="pStyle">{this.props.secondRow}</p>
            </div>
        )
    }
});

// 創建設置h1樣式對象Name
var hStyle = {
    backgroundColor: "green",
    color: "red"
}

ReactDOM.render(
    <ShowMessage firstRow="你好" secondRow="小明"/>,
    document.getElementById('root')
);

這里p使用的是選擇樣式,將樣式寫在index.css中,在使用的過程中進行導入

import './index.css';

.pStyle {
  font-size: 20px;
}

在React中使用選擇器樣式設置組件樣式時,屬性名不能使用class,需要使用className替換。同樣的還有使用htmlFor替換for

(3)復合組件

復合組件 也稱為組合組件,創建多個組件合成一個組件。定義一個組件的WebShow。功能:輸出網站的名字和網址,網址是一個可以點擊的鏈接。

分析:定義一個組件WebName負責輸出網站名字,定義組件WebLink顯示網站的網址,并且可以點擊

// 定義WebName組件
var WebName = React.createClass({
    render: function() {
        return (
            <h1>{this.props.webName}</h1>
        )
    }
});

// 定義WebLink組件
var WebLink = React.createClass({
    render: function() {
        return (
             <a href={this.props.webLink}>{this.props.webLink}</a>
        )
    }
});

// 組合組件WebShow
var WebShow = React.createClass({
    render: function() {
        return (
            <div>
                <WebName webName={this.props.webName}/>
                <WebLink webLink={this.props.webLink}/>
            </div>
        )
    }
});


ReactDOM.render(
    <WebShow webName="新浪" webLink="http://www.sina.com.cn"/>,
    document.getElementById('root')
);

5.props

props是組件自身的屬性,一般用于嵌套的內外層組件中,負責傳遞數據(通常是由父層向子層組件傳遞)

注意:props對象中的屬性與組件的屬性一一對應,不要直接直接去修改props中屬性的值

...this.props

這個是props提供的語法糖,可以將父組件中的全部屬性都復制給子組件

下邊定義一個Link組件,Link組件只包含一個<a>,我們不給<a>設置任何屬性,所有屬性全部從父組件復制得到

var Link = React.createClass({
    render: function () {
        return <a {...this.props}>{this.props.name}</a>
    }
});

ReactDOM.render(
    <Link  name="百度" />,
    document.getElementById("root")
)

this.props.children

children組件是一個例外,不是跟組件的屬性對應的,它表示組件的所有子節點

下邊展示一種列表,在HTML5中有一種標簽:<ul> <ol> <li>。定義一個列表組件,列表項中顯示的內容,以及列表項的數量都由外部決定。

var ListComponent = React.createClass({
    render: function () {
        return (
            <ul>
                {
                    // 列表項數量不確定,在創建模板時才能確定,利用this.props.children從父組件獲取需要展示的列表項內容
                    // 獲取到列表項內容后,需要遍歷children,逐行進行設置
                    // 使用React.Children.map方法 返回值:數組對象,這里數組中的元素是<li>
                    React.Children.map(this.props.children, function (child) {
                        // child是遍歷得到的父組件的子節點
                        return <li>{child}</li>
                    })
                }
            </ul>
        );
    }
});

ReactDOM.render(
    (
        <ListComponent>
            <h1>百度文庫</h1>
            <a >http://www.baidu.com</a>
            <h1>百度文庫</h1>
            <a >http://www.baidu.com</a>
            <h2>百度文庫</h2>
         </ListComponent>
    ),
    document.getElementById("root")
);

屬性驗證

用來驗證外部設置的值是否符合組件對屬性類型的要求,也是組件類的屬性。用來驗證組件實例的屬性是否符合要求

var ShowTitle = React.createClass({
    // 屬性驗證
    propTypes: {
        // title 必須為字符串
        title: React.PropTypes.string.isRequired
    },
    render: function () {
        return <h1>{this.props.title}</h1>
    }
});

ReactDOM.render(
    // 這里如果傳入title=1234,運行就會出錯,因為屬性驗證要求組件傳入的屬性時字符串類型的
    <ShowTitle title="1234"/>,
    document.getElementById("root")
);

設置組件屬性的默認值

通過實現組件的getDefaultProps方法,對屬性設置默認值

var ShowTitle = React.createClass({
    getDefaultProps: function () {
        return {
            title: "小明"
        }
    },
    
    render: function () {
        return <h1>{this.props.title}</h1>
    }
});

ReactDOM.render(
    // 這里雖然沒有傳入屬性值,但是屬性設置了默認值,因此渲染結果是顯示出“小明”字樣
    <ShowTitle />,
    document.getElementById("root")
);

6.state

事件處理
定義一個組件,組件中包含一個button,給button綁定onClick事件

var MyButton = React.createClass({
    // React中的事件名稱,首字母小寫,駝峰命名法
    handleClick: function () {
        alert("點擊按鈕觸發的效果")
    },

    render: function () {
        return <button onClick={this.handleClick}>{this.props.buttonTitle}</button>
    }
});

ReactDOM.render(
    <MyButton buttonTitle="按鈕" />,
    document.getElementById("root")
);

state狀態
state和props一樣,都是組件自身的屬性,通過調用this.state

下邊創建一個CheckButton組件,包含一個checkbox類型的<input>,復選框在選中和未選中兩種狀態下會顯示不同的文字,即根據狀態渲染

var CheckButton = React.createClass({
    // 定義初始狀態
    getInitialState: function () {
        return {
            // 在這個對象中設置的屬性,將會存儲在state中
            isCheck: false
        }
    },

    // 定義事件綁定的方法
    handleChange: function () {
        // 修改狀態值,通過this.state讀取設置的狀態值
        this.setState({
            isCheck: !this.state.isCheck
        });
    },

    render: function () {
        // 根據狀態值,設置顯示的文字
        // 注意: 在JSX中不能直接使用if, 如果需要條件判斷需要在外邊寫個方法將結果傳進來就行,可以使用三目運算符
        var text = this.state.isCheck ? "已選中" : "未選中";
        return (
            // 返回結果只能有一個根節點
            <div>
                <input type="checkbox" onChange={this.handleChange} />
                {text}
            </div>
        );
    }
});

ReactDOM.render(
    <CheckButton />,
    document.getElementById("root")
);

注意:
當state發生變化時,會調用組件內部的render方法

表單的基本使用

定義一個組件,將用戶在輸入框內輸入的內容進行實時顯示。組件在于用戶的交互過程中,存在狀態的變化,即輸入框的值

var Input = React.createClass({
    getInitialState: function () {
            return {
                value: "請輸入"
            };
    },

    // 輸入框的輸入回傳進來一個參數event
    handeleChange: function (event) {
        // 通過event.target.value讀取用戶輸入的值
        this.setState({
            value: event.target.value
        });
    },

    render: function () {
        var value = this.state.value;
        return(
            <div>
                <input type="text" value={value} onChange={this.handeleChange} />
                <p>{value}</p>
            </div>
        );
    }
});

ReactDOM.render(
    <Input />,
    document.getElementById("root")
);

7.組件的生命周期

生命周期介紹

組件的生命周期可分成三個狀態:

  • Mounting:組件掛載,已插入真實的DOM
  • Updating:組件更新,正在被重新渲染
  • Unmounting: 組件移出,已移出真實DOM

組件的生命周期可分成四個階段:創建、實例化、更新、銷毀

每種狀態對應的方法:

  • Mounting/組件掛在相關:

    • componentWillMount:組件將要掛載。在render方法之前執行,但僅執行一次,即使多次重復渲染該組件,或者改變了組件的state
    • componentDidMount:組件已經掛在。在render之后執行,同一個組件重復渲染只執行一次
  • Updating/組件更新相關:

    • componentWillReceiveProps(object nextProps):已加載組件收到新的props之前調用,注意組件初始化渲染時不會執行
    • shouldComponentUpdate(object nextProps, object nextState):組件判斷是否重新渲染時調用。該接口實際是在組件接收到了新的props或者新的state的時候會立即調用。返回一個Bool值。默認情況下是ture,這就是為什么在前文中說只要調用this.setState方法,就會重新渲染。當返回結果為true時會立即調用下邊另外兩個方法,如果返回false,則不會進行更新。
    • componentWillUpdate(object nextProps, object nextState):組件將要更新
    • componentDidUpdate(object prevProps, object prevState):組件已經更新
  • Unmounting/組件移除相關:

    • componentWillUnmount:在組件要被移除之前的時間點觸發,可以利用該方法來執行一些必要的清理組件相關的工作
  • 生命周期中與props和state相關:

    • getDefaultProps 設置props屬性默認值
    • getInitialState 設置state屬性初始值

生命周期各階段介紹

  • 一、創建階段流程:
    • 只調用getDefaultProps方法
  • 二、實例化階段流程:
    • getInitialState
    • componentWillMount
    • render
    • componentDidMount
  • 三、更新階段流程:
    • componentWillReceiveProps
    • shouldComponentUpdate 如果返回值是false,后三個方法不執行
    • componentWillUpdate
    • render
    • componentDidUpdate
  • 四、銷毀階段流程:
    • 流程:componentWillUnmount
var Demo = React.createClass({
    /*
        一、創建階段
        流程:只調用getDefaultProps方法
    */
    getDefaultProps: function () {
            // 正在創建類的時候被調用,設置this.props的默認值
            console.log("getDefaultProps");
            return {};
    },

    /*
        二、實例化階段
        流程: getInitialState
                    componentWillMount
                    render
                    componentDidMount
    */
    getInitialState: function () {
        // 設置this.state的默認值
        console.log("getInitialState");
        return null;
    },
    componentWillMount: function () {
        // 在render之前調用
        console.log("componentWillMount");
    },
    render: function () {
        // 渲染并返回一個虛擬的DOM
        console.log("render");
        return <div>Hello React</div>
    },
    componentDidMount: function () {
        // 在render之后調用 在該方法中,React會使用render方法返回的虛擬DOM對象創建真實的DOM結構
        // 可以在這個方法中讀取DOM節點
        console.log("componentDidMount");
    },

    /*
        三、更新階段
        流程:componentWillReceiveProps
                 shouldComponentUpdate  如果返回值是false,后三個方法不執行
                 componentWillUpdate
                 render
                 componentDidUpdate
    */
    componentWillReceiveProps: function () {
        console.log("componentWillReceiveProps");
    },
    shouldComponentUpdate: function () {
        console.log("shouldComponentUpdate");
        return true;
    },
    componentWillUpdate: function () {
        console.log("componentWillUpdate");
    },
    componentDidUpdate: function () {
        console.log("componentDidUpdate");
    },

    /*
        四、銷毀階段
        流程:componentWillUnmount
    */
    componentWillUnmount: function () {
        console.log("componentWillUnmount");
    }
});

// 第一次創建并加載組件
ReactDOM.render(
    <Demo />,
    document.getElementById("root")
);
/*
    上邊結果返回的是:
    getDefaultProps
    getInitialState
    componentWillMount
    render
    componentDidMount
*/

// 更新渲染組件
ReactDOM.render(
    <Demo />,
    document.getElementById("root")
);
/*
    更新渲染后的結果:
    componentWillReceiveProps
    shouldComponentUpdate
    componentWillUpdate
    render
    componentDidUpdate

    注意如果將shouldComponentUpdate的返回值設置成false,那么該方法以下的步驟將不會再執行
    返回結果是:
    componentWillReceiveProps
    shouldComponentUpdate
*/

// 移出組件
ReactDOM.unmountComponentAtNode(document.getElementById("root"));
/*
    移出組件后的結果:
    componentWillUnmount
*/
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,563評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,694評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,672評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,965評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,690評論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,019評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,013評論 3 449
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,188評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,718評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,438評論 3 360
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,667評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,149評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,845評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,252評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,590評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,384評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,635評論 2 380

推薦閱讀更多精彩內容

  • 原教程內容詳見精益 React 學習指南,這只是我在學習過程中的一些閱讀筆記,個人覺得該教程講解深入淺出,比目前大...
    leonaxiong閱讀 2,853評論 1 18
  • 深入JSX date:20170412筆記原文其實JSX是React.createElement(componen...
    gaoer1938閱讀 8,097評論 2 35
  • 自己最近的項目是基于react的,于是讀了一遍react的文檔,做了一些記錄(除了REFERENCE部分還沒開始讀...
    潘逸飛閱讀 3,452評論 1 10
  • 為自己健康做定投,身體是自己的,錢沒有可以賺。 當身體出現各種疾病,有錢不一定好用。 每天堅持快走10公里,風雨無...
    一個落魄老男人閱讀 546評論 0 0
  • 朋友深夜打來電話,抽抽噎噎的哭了半天。我一邊極力安慰她,一邊告訴她準媽媽可不能這么悲傷,不然會影響到肚里的孩...
    素顏三步曲閱讀 435評論 1 19