日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

React 学习总结

發布時間:2025/4/14 编程问答 14 豆豆
生活随笔 收集整理的這篇文章主要介紹了 React 学习总结 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

React 入門實例教程

http://www.ruanyifeng.com/blog/2015/03/react.html


現在最熱門的前端框架,毫無疑問是 React 。
上周,基于 React 的 React Native 發布,結果一天之內,就獲得了 5000 顆星,受矚目程度可見一斑。
React 起源于 Facebook 的內部項目,因為該公司對市場上所有 JavaScript MVC 框架,都不滿意,就決定自己寫一套,用來架設 Instagram 的網站。做出來以后,發現這套東西很好用,就在2013年5月開源了。

由于 React 的設計思想極其獨特,屬于革命性創新,性能出眾,代碼邏輯卻非常簡單。所以,越來越多的人開始關注和使用,認為它可能是將來 Web 開發的主流工具。
這個項目本身也越滾越大,從最早的UI引擎變成了一整套前后端通吃的 Web App 解決方案。衍生的 React Native 項目,目標更是宏偉,希望用寫 Web App 的方式去寫 Native App。如果能夠實現,整個互聯網行業都會被顛覆,因為同一組人只需要寫一次 UI ,就能同時運行在服務器、瀏覽器和手機(參見《也許,DOM 不是答案》)。

既然 React 這么熱門,看上去充滿希望,當然應該好好學一下。從技術角度,可以滿足好奇心,提高技術水平;從職業角度,有利于求職和晉升,有利于參與潛力大的項目。但是,好的 React 教程卻不容易找到,這一方面因為這項技術太新,剛剛開始走紅,大家都沒有經驗,還在摸索之中;另一方面因為 React 本身還在不斷變動,API 一直在調整,至今沒發布1.0版。

我學習 React 時,就很苦惱。有的教程討論一些細節問題,對入門沒幫助;有的教程寫得不錯,但比較短,無助于看清全貌。我斷斷續續學了幾個月,看過二十幾篇教程,在這個過程中,將對自己有幫助的 Demo 都收集下來,做成了一個庫 React Demos 。

下面,我就根據這個庫,寫一篇全面又易懂的 React 入門教程。你只需要跟著每一個 Demo 做一遍,就能初步掌握 React 。當然,前提是你必須擁有基本 JavaScript 和 DOM 知識,但是你讀完就會發現,React 所要求的預備知識真的很少。
零、安裝
React 的安裝包,可以到官網下載。不過,React Demos 已經自帶 React 源碼,不用另外安裝,只需把這個庫拷貝到你的硬盤就行了。

$ git clone git@github.com:ruanyf/react-demos.git
如果你沒安裝 git, 那就直接下載 zip 壓縮包。

下面要講解的12個例子在各個 Demo 子目錄,每個目錄都有一個 index.html 文件,在瀏覽器打開這個文件(大多數情況下雙擊即可),就能立刻看到效果。
需要說明的是,React 可以在瀏覽器運行,也可以在服務器運行,但是本教程只涉及瀏覽器。一方面是為了盡量保持簡單,另一方面 React 的語法是一致的,服務器的用法與瀏覽器差別不大。Demo13 是服務器首屏渲染的例子,有興趣的朋友可以自己去看源碼。

一、HTML 模板

使用 React 的網頁源碼,結構大致如下。

<!DOCTYPE html> <html><head><script src="../build/react.js"></script><script src="../build/react-dom.js"></script><script src="../build/browser.min.js"></script></head><body><div id="example"></div><script type="text/babel">// ** Our code goes here! **</script></body> </html>

上面代碼有兩個地方需要注意。首先,最后一個 <script> 標簽的 type 屬性為 text/babel 。這是因為 React 獨有的 JSX 語法,跟 JavaScript 不兼容。凡是使用 JSX 的地方,都要加上 type="text/babel" 。
其次,上面代碼一共用了三個庫: react.js 、react-dom.js 和 Browser.js ,它們必須首先加載。其中,react.js 是 React 的核心庫,react-dom.js 是提供與 DOM 相關的功能,Browser.js 的作用是將 JSX 語法轉為 JavaScript 語法,這一步很消耗時間,實際上線的時候,應該將它放到服務器完成。

$ babel src --out-dir build
上面命令可以將 src 子目錄的 js 文件進行語法轉換,轉碼后的文件全部放在 build 子目錄。

二、ReactDOM.render()

ReactDOM.render 是 React 的最基本方法,用于將模板轉為 HTML 語言,并插入指定的 DOM 節點。

ReactDOM.render(
? <h1>Hello, world!</h1>,
? document.getElementById('example')
);
上面代碼將一個 h1 標題,插入 example 節點(查看 demo01),運行結果如下。

三、JSX 語法

上一節的代碼, HTML 語言直接寫在 JavaScript 語言之中,不加任何引號,這就是 JSX 的語法,它允許 HTML 與 JavaScript 的混寫(查看 Demo02 )。

var names = ['Alice', 'Emily', 'Kate'];

ReactDOM.render(
? <div>
? {
? ? names.map(function (name) {
? ? ? return <div>Hello, {name}!</div>
? ? })
? }
? </div>,
? document.getElementById('example')
);
上面代碼體現了 JSX 的基本語法規則:遇到 HTML 標簽(以 < 開頭),就用 HTML 規則解析;遇到代碼塊(以 { 開頭),就用 JavaScript 規則解析。上面代碼的運行結果如下。

JSX 允許直接在模板插入 JavaScript 變量。如果這個變量是一個數組,則會展開這個數組的所有成員(查看 demo03 )。

var arr = [
? <h1>Hello world!</h1>,
? <h2>React is awesome</h2>,
];
ReactDOM.render(
? <div>{arr}</div>,
? document.getElementById('example')
);
上面代碼的arr變量是一個數組,結果 JSX 會把它的所有成員,添加到模板,運行結果如下。

四、組件

React 允許將代碼封裝成組件(component),然后像插入普通 HTML 標簽一樣,在網頁中插入這個組件。React.createClass 方法就用于生成一個組件類(查看 demo04)。


var HelloMessage = React.createClass({
? render: function() {
? ? return <h1>Hello {this.props.name}</h1>;
? }
});


ReactDOM.render(
? <HelloMessage name="John" />,
? document.getElementById('example')
);
上面代碼中,變量 HelloMessage 就是一個組件類。模板插入 <HelloMessage /> 時,會自動生成 HelloMessage 的一個實例(下文的"組件"都指組件類的實例)。所有組件類都必須有自己的 render 方法,用于輸出組件。
注意,組件類的第一個字母必須大寫,否則會報錯,比如HelloMessage不能寫成helloMessage。另外,組件類只能包含一個頂層標簽,否則也會報錯。


var HelloMessage = React.createClass({
? render: function() {
? ? return <h1>
? ? ? Hello {this.props.name}
? ? </h1><p>
? ? ? some text
? ? </p>;
? }
});
上面代碼會報錯,因為HelloMessage組件包含了兩個頂層標簽:h1和p。
組件的用法與原生的 HTML 標簽完全一致,可以任意加入屬性,比如 <HelloMessage name="John"> ,就是 HelloMessage 組件加入一個 name 屬性,值為 John。組件的屬性可以在組件類的 this.props 對象上獲取,比如 name 屬性就可以通過 this.props.name 讀取。上面代碼的運行結果如下。


添加組件屬性,有一個地方需要注意,就是 class 屬性需要寫成 className ,for 屬性需要寫成 htmlFor ,這是因為 class 和 for 是 JavaScript 的保留字。

五、this.props.children

this.props 對象的屬性與組件的屬性一一對應,但是有一個例外,就是 this.props.children 屬性。它表示組件的所有子節點(查看 demo05)。


var NotesList = React.createClass({
? render: function() {
? ? return (
? ? ? <ol>
? ? ? {
? ? ? ? React.Children.map(this.props.children, function (child) {
? ? ? ? ? return <li>{child}</li>;
? ? ? ? })
? ? ? }
? ? ? </ol>
? ? );
? }
});


ReactDOM.render(
? <NotesList>
? ? <span>hello</span>
? ? <span>world</span>
? </NotesList>,
? document.body
);
上面代碼的 NoteList 組件有兩個 span 子節點,它們都可以通過 this.props.children 讀取,運行結果如下。


這里需要注意, this.props.children 的值有三種可能:如果當前組件沒有子節點,它就是 undefined ;如果有一個子節點,數據類型是 object ;如果有多個子節點,數據類型就是 array 。所以,處理 this.props.children 的時候要小心。
React 提供一個工具方法 React.Children 來處理 this.props.children 。我們可以用 React.Children.map 來遍歷子節點,而不用擔心 this.props.children 的數據類型是 undefined 還是 object。更多的 React.Children 的方法,請參考官方文檔。

六、PropTypes

組件的屬性可以接受任意值,字符串、對象、函數等等都可以。有時,我們需要一種機制,驗證別人使用組件時,提供的參數是否符合要求。
組件類的PropTypes屬性,就是用來驗證組件實例的屬性是否符合要求(查看 demo06)。


var MyTitle = React.createClass({
? propTypes: {
? ? title: React.PropTypes.string.isRequired,
? },


? render: function() {
? ? ?return <h1> {this.props.title} </h1>;
? ?}
});
上面的Mytitle組件有一個title屬性。PropTypes 告訴 React,這個 title 屬性是必須的,而且它的值必須是字符串。現在,我們設置 title 屬性的值是一個數值。


var data = 123;


ReactDOM.render(
? <MyTitle title={data} />,
? document.body
);
這樣一來,title屬性就通不過驗證了。控制臺會顯示一行錯誤信息。


Warning: Failed propType: Invalid prop `title` of type `number` supplied to `MyTitle`, expected `string`.
更多的PropTypes設置,可以查看官方文檔。
此外,getDefaultProps 方法可以用來設置組件屬性的默認值。


var MyTitle = React.createClass({
? getDefaultProps : function () {
? ? return {
? ? ? title : 'Hello World'
? ? };
? },


? render: function() {
? ? ?return <h1> {this.props.title} </h1>;
? ?}
});


ReactDOM.render(
? <MyTitle />,
? document.body
);
上面代碼會輸出"Hello World"。

七、獲取真實的DOM節點

組件并不是真實的 DOM 節點,而是存在于內存之中的一種數據結構,叫做虛擬 DOM (virtual DOM)。只有當它插入文檔以后,才會變成真實的 DOM 。根據 React 的設計,所有的 DOM 變動,都先在虛擬 DOM 上發生,然后再將實際發生變動的部分,反映在真實 DOM上,這種算法叫做 DOM diff ,它可以極大提高網頁的性能表現。
但是,有時需要從組件獲取真實 DOM 的節點,這時就要用到 ref 屬性(查看 demo07 )。


var MyComponent = React.createClass({
? handleClick: function() {
? ? this.refs.myTextInput.focus();
? },
? render: function() {
? ? return (
? ? ? <div>
? ? ? ? <input type="text" ref="myTextInput" />
? ? ? ? <input type="button" value="Focus the text input" onClick={this.handleClick} />
? ? ? </div>
? ? );
? }
});


ReactDOM.render(
? <MyComponent />,
? document.getElementById('example')
);
上面代碼中,組件 MyComponent 的子節點有一個文本輸入框,用于獲取用戶的輸入。這時就必須獲取真實的 DOM 節點,虛擬 DOM 是拿不到用戶輸入的。為了做到這一點,文本輸入框必須有一個 ref 屬性,然后 this.refs.[refName] 就會返回這個真實的 DOM 節點。
需要注意的是,由于 this.refs.[refName] 屬性獲取的是真實 DOM ,所以必須等到虛擬 DOM 插入文檔以后,才能使用這個屬性,否則會報錯。上面代碼中,通過為組件指定 Click 事件的回調函數,確保了只有等到真實 DOM 發生 Click 事件之后,才會讀取 this.refs.[refName] 屬性。
React 組件支持很多事件,除了 Click 事件以外,還有 KeyDown 、Copy、Scroll 等,完整的事件清單請查看官方文檔。

八、this.state

組件免不了要與用戶互動,React 的一大創新,就是將組件看成是一個狀態機,一開始有一個初始狀態,然后用戶互動,導致狀態變化,從而觸發重新渲染 UI (查看 demo08 )。


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 ? 'like' : 'haven\'t liked';
? ? return (
? ? ? <p onClick={this.handleClick}>
? ? ? ? You {text} this. Click to toggle.
? ? ? </p>
? ? );
? }
});


ReactDOM.render(
? <LikeButton />,
? document.getElementById('example')
);
上面代碼是一個 LikeButton 組件,它的 getInitialState 方法用于定義初始狀態,也就是一個對象,這個對象可以通過 this.state 屬性讀取。當用戶點擊組件,導致狀態變化,this.setState 方法就修改狀態值,每次修改以后,自動調用 this.render 方法,再次渲染組件。
由于 this.props 和 this.state 都用于描述組件的特性,可能會產生混淆。一個簡單的區分方法是,this.props 表示那些一旦定義,就不再改變的特性,而 this.state 是會隨著用戶互動而產生變化的特性。

九、表單

用戶在表單填入的內容,屬于用戶跟組件的互動,所以不能用 this.props 讀取(查看 demo9 )。


var Input = React.createClass({
? getInitialState: function() {
? ? return {value: 'Hello!'};
? },
? handleChange: function(event) {
? ? this.setState({value: event.target.value});
? },
? render: function () {
? ? var value = this.state.value;
? ? return (
? ? ? <div>
? ? ? ? <input type="text" value={value} onChange={this.handleChange} />
? ? ? ? <p>{value}</p>
? ? ? </div>
? ? );
? }
});


ReactDOM.render(<Input/>, document.body);
上面代碼中,文本輸入框的值,不能用 this.props.value 讀取,而要定義一個 onChange 事件的回調函數,通過 event.target.value 讀取用戶輸入的值。textarea 元素、select元素、radio元素都屬于這種情況,更多介紹請參考官方文檔。

十、組件的生命周期

組件的生命周期分成三個狀態:
Mounting:已插入真實 DOM
Updating:正在被重新渲染
Unmounting:已移出真實 DOM
React 為每個狀態都提供了兩種處理函數,will 函數在進入狀態之前調用,did 函數在進入狀態之后調用,三種狀態共計五種處理函數。
componentWillMount()
componentDidMount()
componentWillUpdate(object nextProps, object nextState)
componentDidUpdate(object prevProps, object prevState)
componentWillUnmount()
此外,React 還提供兩種特殊狀態的處理函數。
componentWillReceiveProps(object nextProps):已加載組件收到新的參數時調用
shouldComponentUpdate(object nextProps, object nextState):組件判斷是否重新渲染時調用
這些方法的詳細說明,可以參考官方文檔。下面是一個例子(查看 demo10 )。


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 (
? ? ? <div style={{opacity: this.state.opacity}}>
? ? ? ? Hello {this.props.name}
? ? ? </div>
? ? );
? }
});


ReactDOM.render(
? <Hello name="world"/>,
? document.body
);
上面代碼在hello組件加載以后,通過 componentDidMount 方法設置一個定時器,每隔100毫秒,就重新設置組件的透明度,從而引發重新渲染。
另外,組件的style屬性的設置方式也值得注意,不能寫成


style="opacity:{this.state.opacity};"
而要寫成


style={{opacity: this.state.opacity}}
這是因為 React 組件樣式是一個對象,所以第一重大括號表示這是 JavaScript 語法,第二重大括號表示樣式對象。

十一、Ajax

組件的數據來源,通常是通過 Ajax 請求從服務器獲取,可以使用 componentDidMount 方法設置 Ajax 請求,等到請求成功,再用 this.setState 方法重新渲染 UI (查看 demo11 )。


var UserGist = React.createClass({
? getInitialState: function() {
? ? return {
? ? ? username: '',
? ? ? lastGistUrl: ''
? ? };
? },


? componentDidMount: function() {
? ? $.get(this.props.source, function(result) {
? ? ? var lastGist = result[0];
? ? ? if (this.isMounted()) {
? ? ? ? this.setState({
? ? ? ? ? username: lastGist.owner.login,
? ? ? ? ? lastGistUrl: lastGist.html_url
? ? ? ? });
? ? ? }
? ? }.bind(this));
? },


? render: function() {
? ? return (
? ? ? <div>
? ? ? ? {this.state.username}'s last gist is
? ? ? ? <a href={this.state.lastGistUrl}>here</a>.
? ? ? </div>
? ? );
? }
});


ReactDOM.render(
? <UserGist source="https://api.github.com/users/octocat/gists" />,
? document.body
);
上面代碼使用 jQuery 完成 Ajax 請求,這是為了便于說明。React 本身沒有任何依賴,完全可以不用jQuery,而使用其他庫。
我們甚至可以把一個Promise對象傳入組件,請看Demo12。


ReactDOM.render(
? <RepoList
? ? promise={$.getJSON('https://api.github.com/search/repositories?q=javascript&sort=stars')}
? />,
? document.body
);
上面代碼從Github的API抓取數據,然后將Promise對象作為屬性,傳給RepoList組件。
如果Promise對象正在抓取數據(pending狀態),組件顯示"正在加載";如果Promise對象報錯(rejected狀態),組件顯示報錯信息;如果Promise對象抓取數據成功(fulfilled狀態),組件顯示獲取的數據。


var RepoList = React.createClass({
? getInitialState: function() {
? ? return { loading: true, error: null, data: null};
? },


? componentDidMount() {
? ? this.props.promise.then(
? ? ? value => this.setState({loading: false, data: value}),
? ? ? error => this.setState({loading: false, error: error}));
? },


? render: function() {
? ? if (this.state.loading) {
? ? ? return <span>Loading...</span>;
? ? }
? ? else if (this.state.error !== null) {
? ? ? return <span>Error: {this.state.error.message}</span>;
? ? }
? ? else {
? ? ? var repos = this.state.data.items;
? ? ? var repoList = repos.map(function (repo) {
? ? ? ? return (
? ? ? ? ? <li>
? ? ? ? ? ? <a href={repo.html_url}>{repo.name}</a> ({repo.stargazers_count} stars) <br/> {repo.description}
? ? ? ? ? </li>
? ? ? ? );
? ? ? });
? ? ? return (
? ? ? ? <main>
? ? ? ? ? <h1>Most Popular JavaScript Projects in Github</h1>
? ? ? ? ? <ol>{repoList}</ol>
? ? ? ? </main>
? ? ? );
? ? }
? }
});

十二、參考鏈接

React's official site
React's official examples
React (Virtual) DOM Terminology, by Sebastian Markb?ge
The React Quick Start Guide, by Jack Callister
Learning React.js: Getting Started and Concepts, by Ken Wheeler
Getting started with React, by Ryan Clark
React JS Tutorial and Guide to the Gotchas, by Justin Deal
React Primer, by Binary Muse
jQuery versus React.js thinking, by zigomir

總結

以上是生活随笔為你收集整理的React 学习总结的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 神马午夜精品 | a视频在线| 精品久久影视 | 免费激情视频网站 | 小柔的淫辱日记(1~7) | 中文字幕电影av | 91视频精品 | 亚洲精品美女 | 久久久久久久性 | 在线看欧美 | 久久撸视频 | 在线免费观看黄色网址 | 懂色中文一区二区在线播放 | 国产精品毛片久久久久久久 | 欧美黄色网络 | 日韩三级一区二区三区 | 美女试爆场恐怖电影在线观看 | 日本高清在线播放 | 日本中文一区 | 超碰中文字幕在线 | 亚洲精品在线影院 | 日韩黄色片在线观看 | 91中出| 欧美少妇b| 男女草逼 | 日本欧美亚洲 | 国产精品免费一区二区三区都可以 | 四虎黄色 | 99精品热 | 国产91精品在线观看 | 久久久久人妻一区精品 | 欧美视频在线观看一区 | 青青草视频| 美色视频 | 日韩一区欧美二区 | 中国黄色免费网站 | 国产777 | 九九热8| 国产精品mm | 99精品久久99久久久久 | 男同精品| 青青青青操 | 人碰人人 | 亚洲天堂第一 | 中文字幕在线观看视频一区二区 | 黑人av | 香蕉久久久 | 妻色成人网 | 精品久久久噜噜噜久久久 | 五月婷婷丁香综合 | 可以看的毛片 | 久热综合 | 国产精品欧美在线 | 91欧美激情一区二区三区 | 亚洲经典久久 | 爱爱视频网址 | 午夜伦理视频 | 欧美色图影院 | 毛片在线观看网站 | 欧美激情成人 | 天天插天天爽 | av毛片大全 | 欧美精品在线播放 | 日韩视频一二三 | 91看片免费版| 全黄一级裸体 | 亚洲av最新在线网址 | 激情偷拍| 最新中文av| 亚洲视频在线观看免费视频 | 中文字幕精品久久久久人妻红杏1 | 成人精品一区二区三区电影 | 无码av免费毛片一区二区 | 亚洲精品一区在线 | 国产精品白丝喷水在线观看 | 亚洲国产剧情在线观看 | 精品动漫一区 | 国产精品有码 | 成人性视频网站 | 久久午夜一区 | 天天插日日插 | 麻豆av电影网 | 成人性生交大片免费看中文 | 成人午夜视频一区二区播放 | 亚洲黄色小视频 | 综合久久综合久久 | 97超级碰碰碰 | 亚洲国产一级 | 国产欧美一区二区精品性色超碰 | 春色激情| 午夜精品小视频 | 成人激情站 | 日批视频在线免费看 | 欧美性激情| 中文字幕av在线免费 | 欧美精品成人久久 | 西野翔之公侵犯中文字幕 | 黄色高清视频在线观看 | 国产成人h |