使用React 應當注意的幾個地方

目標人羣

獻給熟悉基礎的React語法的剛接觸React的同窗~前端

若是你已經寫過半年以上的React那也不用看了,畢竟我水平並不高react

What's React

React 是一個不存在的網絡公司Facebook出的JavaScript視圖框架。git

他們官網寫着es6

JUST THE UIgithub

VIRTUAL DOMajax

DATA FLOWchrome

這三個特性。npm

當我第一次看到的時候在想,這丫的弱爆了,人家動輒就MVCMVVM的框架,你居然只寫了一個UI?json

固然,當時個人想法確定是錯的。gulp

React擁有很是高的性能,結合單向數據流還有組件化思想,能夠很舒服的作出現代化的前端產品。

Start

首先,得有開發環境。

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

看到這裏,若是同窗你不熟悉ES2015的語法可能就感受看不懂這是什麼了,這仍是JavaScript麼?

若是真的對ES2015語法不太熟悉,能夠看看阮一峯老師的書:ECMAScript 6入門

我很是的喜歡ES6的語法,由於寫起來很是的清晰明瞭。看着舒服。

只是絕大部分瀏覽器如今並不能徹底支持ES6,因此須要babel轉義。

上面的gulp的jsx task就是完成這樣的轉義。

Spelling Component

這個問題和中文有關。

當初我由於英文不過關,總是把Component寫成Components或者component或者components

這幾種都是不行的。都會形成錯誤,注意必定必定嚴格的用Component,因此我建議直接複製個人Live template。

Use strict

其實挺糾結的。由於用babel的話他會轉義代碼,寫不寫'use strict'其實一個樣。

然而我仍是建議加上'use strict'。

若是放棄babel,那麼咱們也能夠寫出嚴格的js代碼,這樣多好。

bind(this)

這裏有些很奇怪的問題。有一些狀況下這樣寫會出錯

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)} />

這個問題並無深究,留待再碰到再解決吧。

Ajax

不可避免的,構建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

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

這個是深坑啊。埋了我好長時間。。。

你要是老老實實跟着官網寫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-dom

我目前碰到的最深的坑,沒有之一。

我記得以前的寫法是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的坑爹文檔。這裏得說說react-router的坑爹版本號

安裝的時候千萬別懶省事,否則就直接拷貝:

$ npm install --save history react-router@latest

我當時就是懶得打最後的@latest,致使怎麼都沒辦法顯示效果。也是找了大半天的問題。後來才發現Router是undefined

別懶省事就成了。

Others

關於Flux理解不夠深,也沒有用。

反正我如今看到react-router就後背涼颼颼的。Redux也是這老大作的吧。感受菊花一緊。。。

下一步

從一開始的彆扭,到如今不寫React的彆扭,轉變其實仍是蠻大的。

關於React的探索,這裏並非終點。

其餘的,動畫,Flux,React-Native,Meteor都是將來要研究的東西。

好好學習吧,少年~

相關文章
相關標籤/搜索