獻給熟悉基礎的React語法的剛接觸React的同窗~前端
若是你已經寫過半年以上的React那也不用看了,畢竟我水平並不高react
React 是一個不存在的網絡公司Facebook出的JavaScript視圖框架。git
他們官網寫着es6
JUST THE UIgithub
VIRTUAL DOMajax
DATA FLOWchrome
這三個特性。npm
當我第一次看到的時候在想,這丫的弱爆了,人家動輒就MVC,MVVM的框架,你居然只寫了一個UI?json
固然,當時個人想法確定是錯的。gulp
React擁有很是高的性能,結合單向數據流還有組件化思想,能夠很舒服的作出現代化的前端產品。
首先,得有開發環境。
Node的安裝推薦用nvm,我在上一篇《編譯個人開發環境》裏有寫。
主要是在項目裏得加入編譯jsx到正常的js
$ npm install --save gulp browserify babelify vinyl-source-stream babel-core
在gulpfile.babel.js
里加上任務
import gulp from 'gulp'; import browserify from 'browserify'; import babelify from 'babelify'; import source from 'vinyl-source-stream'; gulp.task('jsx', () => { return browserify('src/app.js') .transform(babelify.configure({ stage:0 })) .bundle() .pipe(source('bundle.js')) .pipe(gulp.dest('dist/')); });
這樣,開發環境就大功告成了。
然而,然而。
起初的時候要寫React這種代碼是比較痛苦的。
日常就是寫HTML,而後主要經過jQuery調整頁面,完成一些顯示的功能。
而React是強迫組件化,強制性的用組件化來構造前端。
這裏寫個人Live template吧,直接複製粘貼到WebStorm就能夠啦
import React from 'react'; class $className$ extends React.Component { render() { return ( $content$ ); } } export default $className$;
看到這裏,若是同窗你不熟悉ES2015的語法可能就感受看不懂這是什麼了,這仍是JavaScript麼?
若是真的對ES2015語法不太熟悉,能夠看看阮一峯老師的書:ECMAScript 6入門
我很是的喜歡ES6的語法,由於寫起來很是的清晰明瞭。看着舒服。
只是絕大部分瀏覽器如今並不能徹底支持ES6,因此須要babel轉義。
上面的gulp的jsx task就是完成這樣的轉義。
這個問題和中文有關。
當初我由於英文不過關,總是把Component
寫成Components
或者component
或者components
。
這幾種都是不行的。都會形成錯誤,注意必定必定嚴格的用Component
,因此我建議直接複製個人Live template。
其實挺糾結的。由於用babel的話他會轉義代碼,寫不寫'use strict'其實一個樣。
然而我仍是建議加上'use strict'。
若是放棄babel,那麼咱們也能夠寫出嚴格的js代碼,這樣多好。
這裏有些很奇怪的問題。有一些狀況下這樣寫會出錯
class App extends React.Component { handleChange(e) { console.log(this); } render() { return ( <input type="text" onChange={this.handleChange} /> ); } }
對,這個this,有時候不知道爲何this指向就會變。
若是你碰到了這樣的問題,可能加一個綁定當前this會有效:
<input type="text" onChange={this.handleChange.bind(this)} />
這個問題並無深究,留待再碰到再解決吧。
不可避免的,構建SPA確定是要用到Ajax的。
我有時候也想用fetch
,可是,此次我慫了。 瀏覽器兼容性實在是太差了。
chrome 42 才支持。不能期望其餘瀏覽器跟上了。
言歸正傳,通常狀況下Ajax數據是要傳到state
裏面的,因此通常是這樣的:
class App extends React.Component { fetchSomething() { $.ajax({ url: 'http://foo.com', dataType: 'json', method: 'GET', success: function(res) { this.setState({ res: res }); } }); } render() { return (...); } }
若是你真的這樣寫,恭喜你,你會碰到兩個坑!
一個是this
,在success中的this指向但是XMLHttpRequest的對象哦,並非App 的class。這個時候通常用的是在外面保存this,而後裏面調用
let that = this; that.setState({});
第二個坑更隱蔽。我當初愣是沒想起來。
異步
即便常常寫原生js也很容易忽視這個問題。
ajax請求默認是異步的,也就是說,數據還沒有傳送到客戶端的時候,js就已經跑完了客戶端的全部代碼(好幾遍)。V8那個效率,你懂的。
問題來了。數據沒有到,那麼this.setState也就沒有觸發,那麼後面用數據怎麼辦?
GG
好了,既然原理知道了,那麼解決方法也就很簡單了,在Ajax請求的時候改爲同步的
$.ajax({ url: '/foo/bar', dataType: 'json', async: false, success: function(res){ this.setState({res}); } });
這裏也就形成了一個問題,Ajax請求在了主線程上。網絡堵塞就完蛋了。。。額,再說吧。
constructor是ES6的class的構造函數,在React中用處很是的大
class App extends React.Component { constructor(props) { super(props); // do something this.state = { author: 'Annatar' } } render() { return (...); } }
構造函數必須傳入props,而且在第一行就得首先調用父類的構造函數。
state的設置在constructor中並非setState了,而是變成了賦值。就像上面的那樣
我就在constructor中調用Ajax。。。
這個是深坑啊。埋了我好長時間。。。
你要是老老實實跟着官網寫props,就像這樣
class App extends React.Component { static PropTypes = { url: React.PropTypes.string.isRequired } static defaultProps = { url: '/foo/bar' } render() { return (...); } }
哈哈,正常狀況是會報錯的!
我通過查資料才得知static
目前是ES7
草案上的屬性,可是React官方已經推薦用了。
默認的babel並無開啓ES7的轉義。因此會報錯,不認識。
因此我在gulp配置文件中把babelify的stage改爲了0.表示全部屬性都用,
而後就經過了
我目前碰到的最深的坑,沒有之一。
我記得以前的寫法是React.render(<App />, document.body)
,嗯,挺正常的。好
後來升級到0.14.0,要引入react-dom,寫成這樣也挺好的:
import ReactDOM from 'react-dom'; import App from './app'; ReactDOM(<App />, document.body);
嗯,挺好的。看着不錯嘛。
可是。。。爲毛小版本的升級0.14.2就要換成ReactDOM.render
!
最坑的是react-router
這個項目裏面的readme裏寫的是錯誤的寫法!(如今是正確的)
我當時困惑了足足兩個小時。後來哪裏都肯定了沒有問題。就是找不出緣由,後來就輸出ReactDOM才發現裏面丫的藏着一個render方法。這才正確。
必定記得,多看文檔。注意,注意,注意,千萬只看官方的文檔,其餘的誰都不可靠!
import ReactDOM from 'react-dom'; // import {render} from 'react-dom'; 也行 import App from './app'; ReactDOM.render(<App />, document.body); // render(<App />, document.body);
上面講了react-router的坑爹文檔。這裏得說說react-router的坑爹版本號
安裝的時候千萬別懶省事,否則就直接拷貝:
$ npm install --save history react-router@latest
我當時就是懶得打最後的@latest
,致使怎麼都沒辦法顯示效果。也是找了大半天的問題。後來才發現Router是undefined
別懶省事就成了。
關於Flux理解不夠深,也沒有用。
反正我如今看到react-router
就後背涼颼颼的。Redux
也是這老大作的吧。感受菊花一緊。。。
從一開始的彆扭,到如今不寫React的彆扭,轉變其實仍是蠻大的。
關於React的探索,這裏並非終點。
其餘的,動畫,Flux,React-Native,Meteor都是將來要研究的東西。
好好學習吧,少年~