react基礎(1)

在 react入門系列 裏面,介紹了一些react的基礎知識,在react基礎部分,會結合手腳架工具進行更多的總結。css

關於webpack我在這裏就不講解了,有須要的小夥伴能夠本身去百度一下學習資料,我這裏會貼出來現成的東西供你們使用。html

關於es6的內容,在寫案例的時候會有涉及,我會貼出來相應的教程,沒有了解過es6的小夥伴能夠去看一下。node

 

建立項目

1. 建立一個項目文件夾(我是在D盤建立了一個react文件)react

 

2. 進入react文件夾,新建兩個文件package.json和webpack.config.js,新建一個src文件夾,以下所示:jquery

下面爲了方便你們知道是什麼文件夾下的什麼文件,我都會以react/xx/xx.xx這樣的方式來標明是哪一個文件或文件夾,例如上圖中的package.json,我就會寫成react/package.jsonwebpack

 

package.json和webpack.config.js內容以下git

 

react/package.jsones6

 

{
  "private": true,
  "entry": {},
  "dependencies": {
    "antd": "^1.1.0",
    "atool-build": "0.7.x",
    "babel-plugin-antd": "0.4.x",
    "babel-plugin-transform-runtime": "^6.8.0",
    "babel-runtime": "^6.6.1",
    "classnames": "^2.2.3",
    "es3ify-loader": "^0.2.0",
    "history": "^2.0.1",
    "isomorphic-fetch": "^2.2.1",
    "js-cookie": "^2.1.1",
    "react": "^15.3.2",
    "react-dom": "^15.0.2",
    "react-redux": "^4.4.5",
    "react-router": "^2.0.1",
    "spmhandlebars-loader": "^0.1.0"
  },
  "devDependencies": {
    "atool-test-mocha": "^0.1.4",
    "babel-eslint": "^6.0.0",
    "dora": "0.3.x",
    "dora-plugin-browser-history": "^0.1.1",
    "dora-plugin-hmr": "0.6.x",
    "dora-plugin-livereload": "0.3.x",
    "dora-plugin-proxy": "0.6.x",
    "dora-plugin-webpack": "0.6.x",
    "eslint": "^2.7.0",
    "eslint-config-airbnb": "6.x",
    "eslint-plugin-react": "4.x",
    "expect": "^1.20.1",
    "glob": "^7.0.3",
    "pre-commit": "1.x",
    "react-redux": "^4.4.5",
    "redux": "^3.5.2"
  },
  "pre-commit": [
    "lint"
  ],
  "scripts": {
    "build": "atool-build",
    "lint": "eslint --ext .js,.jsx src",
    "start": "dora -p 8001 --plugins \"webpack,hmr,proxy,livereload?enableJs=false&injectHost=127.0.0.1,browser-history?index=/src/entries/index.html\"",
    "test": "atool-test-mocha ./src/**/__tests__/*-test.js"
  }
}

 

react/webpack.config.jsgithub

 

// Learn more on how to config.
// - https://github.com/ant-tool/atool-build#配置擴展

const webpack = require('atool-build/lib/webpack');
const fs = require('fs');
const path = require('path');
const glob = require('glob');

module.exports = function(webpackConfig) {
  webpackConfig.babel.plugins.push('transform-runtime');
  webpackConfig.babel.plugins.push(['antd', {
    style: 'css',  // if true, use less
  }]);

  // Enable this if you have to support IE8.
  // webpackConfig.module.loaders.unshift({
  //   test: /\.jsx?$/,
  //   loader: 'es3ify-loader',
  // });

  // Parse all less files as css module.
  webpackConfig.module.loaders.forEach(function(loader, index) {
    if (typeof loader.test === 'function' && loader.test.toString().indexOf('\\.less$') > -1) {
      loader.test = /\.dont\.exist\.file/;
    }
    if (loader.test.toString() === '/\\.module\\.less$/') {
      loader.test = /\.less$/;
    }
  });
  
  webpackConfig.module.loaders.push({
    test: /\.handlebars$/,
    loader: 'spmhandlebars-loader'
  });

  // Load src/entries/*.js as entry automatically.
  const files = glob.sync('./src/entries/*.js');
  const newEntries = files.reduce(function(memo, file) {
    const name = path.basename(file, '.js');
    memo[name] = file;
    return memo;
  }, {});
  webpackConfig.entry = Object.assign({}, webpackConfig.entry, newEntries);

  return webpackConfig;
};

 

這裏對上面兩個文件不作講解,在下面會對package.json作一些講解。(關於webpack的一些內容不會講不少,你們能夠去ant-design學習一下,也能夠本身去網上找webpack的資料學習。)web

 

3. 進入src文件夾,建立entries文件夾,在entries文件夾裏新建index.html、index.css、index.js三個文件

index.html、index.css、index.js三個文件的內容以下(很簡單的代碼,這裏暫時不作講解,先把項目正常運行了)

 

react/src/entries/index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Demo</title>
  <link rel="stylesheet" href="index.css" />
</head>
<body>

<div id="root"></div>

<script src="common.js"></script>
<script src="index.js"></script>

</body>
</html>

react/src/entries/index.css

html, body, #root {
  height: 100%;
}
.box{
    background:red;
}

react/src/entries/index.js

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

function App() {
  return (
    <div className="box">
      demo
    </div>
  );
}

ReactDOM.render(<App />, document.getElementById('root'));

 

4. 安裝依賴

上面的文件都建立好了,返回到react文件夾下,按住shift鍵,同時點擊鼠標右鍵(以下圖所示)

點擊「在此處打開命令窗口」,就能夠看到以下圖所示(注意要在react文件下)

我這裏用的是cmd,你們也能夠用git進行操做

 

下一步 :$ npm install,以下圖所示

若是裝了淘寶鏡像,則用 $ cnpm install淘寶npm鏡像--教程

安裝不成功的就多安裝幾回

安裝成功了,在react文件夾下,就能夠看到node_modules文件夾

 

5. 運行/開發調試 項目

在react文件夾下啓用cmd(或git),$ npm start,以下圖所示

 

在你的瀏覽器訪問 http://localhost:8989/ 看到下圖所示的效果就成功了

 

 6. 構建

$ npm run build,以下圖所示

 

這個時候,你會發現react文件夾裏多了一個dist文件夾(裏面是壓縮後的代碼)

 

 

如今項目已經建立成功了,下面就進入正題了。

首先要講的是和 react入門 系列裏面不同的一些寫法和注意事項。

 

 

JSX

jsx語法和注意事項在 react入門(1) 講過,這裏再也不多講。

 

 

組件

在react入門裏面,咱們也講了建立組件的寫法(react入門1),這裏再來介紹幾種(包含es6的內容,你們能夠去先去了解一下es6

這裏我只對entries文件夾裏的index.js裏的內容進行修改,其餘兩個文件不作修改

修改完文件,若是沒有看到效果,能夠刷新一下http://localhost:8989/ 這個頁面,尚未看到效果的,能夠從新 $ npm start

案例1:

react/src/entries/index.js(index.html和index.css不變)

import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import './index.css';

// 方法1
function One() {
  return (
    <div className="box">demo1</div>
  );
}

// 方法2
const Two = () => {
  return (
    <div>demo2</div>
  );
};
 

// 方法3
class Three extends Component{
    render(){
        return (
            <div>demo3</div>
        )
    }
}

// 方法4
const Four=React.createClass({
  render:function(){
    return (
      <div>
         <One />
         <Two />
         <Three />
         demo4
      </div>
    )
  }
});

ReactDOM.render(
  <Four />,
  document.getElementById('root')
)

 效果以下

分析一下

下面這張圖,結合上面的效果圖裏用綠色勾出來的部分一塊兒看

將Four組件渲染到id名爲root的div裏去。這個id名爲root的div,在react/src/entries/index.html裏能夠找到,以下圖所示

react入門1 有講過具體的原理,這裏再也不多說)

 

下面再來看一下引入,都是用import來引入的,以下圖所示

前面兩個是咱們引入下載的的依賴(react/node_modules這個文件夾裏能夠看到咱們下載了哪些依賴,這裏不細講),最後一個是引入css樣式。

這裏貼一個關於import的教程(原文地址

 

下面主要說一下組件的寫法,上面我列舉了四種寫法,我一一來分析

方法1,這種寫法我就很少說,相信你們都能看懂

 

方法2,這個是es6的箭頭函數,相似方法1,只是換成了es6的寫法。

更加簡潔的寫法以下

const Two = () => <div>demo2</div>;

貼一個箭頭函數的教程幫助你們理解(原文地址

 

 

接下來看一下方法3

方法3,class是es6的內容,以下圖所示,能夠這麼理解

Component是從react裏面來的,以下圖所示

 

這裏咱們的render(){}是直接這麼寫的,而之前咱們都是寫的render:function(){},這也是es6的內容。除了render(){}能夠寫成這樣,其餘的function均可以這麼寫,在下面的例子中你們繼續看。

 

貼一個class的教程幫助你們理解(原文地址

 

 

再來看一下方法4

方法4,和咱們以前在 react入門 系列裏面寫的是同樣的,這裏再也不多說。

 

 

CSS

react入門(1)也介紹了css的寫法,這裏再來介紹一些不一樣的寫法。

 

react/src/entries文件夾裏,新建一個文件index.less,以下所示

react/src/entries/index.less內容以下(less教程,這裏先不講less,不懂less的小夥伴就直接在裏面寫普通的css便可)

.blue{
    color:blue
}
.bg{
    background:grey
}

 案例2:

react/src/entries/index.js(index.html、index.css和index.less不變)

import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import styles from './index.less'

class App extends Component {
  render(){
    return(
      <div>
        <p className='box' style={{color:'#fff'}}>輕音樂</p>
        <p className={styles.blue}>搖滾樂</p>
        <p className={styles.blue+' '+styles.bg}>抒情音樂</p>
        <p className={'box '+styles.blue}>老情歌</p>
      </div>
    )
  }
}

ReactDOM.render(
  <App />,
  document.getElementById('root')
)

效果以下

下面來分析一下

如上圖所示,引入了一個css和一個less文件(這裏styles能夠自定義取名,abc什麼的均可以)

 

下面來看一下css的幾種寫法

  •  

如上圖所示,有兩種寫法

className='box',這個box是在index.css裏的,這也是咱們以前在 react入門1 裏就講過的寫法

style={{color:'#fff'}},這種寫法至關因而行內樣式,要注意:必須寫兩個花括號

如上圖所示,這個styles是從index.less來的(import styles from './index.less'),這種寫法要注意,須要寫一個花括號,在blue前要加styles.

如上圖所示,當你寫多個className時,要注意中間用空格隔開

 

 

事件

react入門2 裏介紹了事件的寫法,這裏結合es6來介紹幾種寫法

案例3:

react/src/entries/index.js(index.html、index.css和index.less不變)

import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import './index.css'; class App extends Component { clicks(){ alert(
1) } render(){ return( <div> <button onClick={this.clicks.bind(this)}>按鈕1</button> <button onClick={ ()=>alert(2) }>按鈕2</button> </div> ) } } ReactDOM.render( <App />, document.getElementById('root') )

 效果以下:

分析一下

如上圖所示,當點擊button的時候,觸發onClick事件,而後調用clicks方法。這裏要注意的是,格式this.xxx.bind(this)

如上圖所示,在花括號裏面寫的是 es6的箭頭函數(箭頭函數在 案例1 貼過教程了)。

 

 

props

在子組件經過this.props.xxx來獲取父組件傳遞的信息,在 react入門(2) 講過,這裏再也不詳細講解

 

 

State

react入門3 裏面介紹了state,都是在getInitialState裏設置初始狀態,以下

getInitialState:function(){
     return {
         val:'red'
     };
}

 es6的寫法又會有所不一樣,下面來看一個例子

 

案例4:

react/src/entries/index.js(index.html、index.css和index.less不變)

import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import './index.css';

class App extends Component {
  constructor() {
      super();
      this.state = {
          val:123
      };
  }

  render(){
    return(
      <div>
        {this.state.val}
      </div>
    )
  }
}

ReactDOM.render(
  <App />,
  document.getElementById('root')
)

下面來分析:

如上圖所示,在設置初始值的時候,是這樣寫的。

 

這裏說幾個注意點:

1. 在constructor(){}裏設置state的初始狀態

這裏貼一個constructor的教程(原文地址

 

 

2. 初始狀態的設置,在 react入門 系列裏面,都是在getInitialState裏直接return的,而這裏要寫在this.state{}

 

3. super關鍵字很重要,若是要在constructor裏用到this,那麼咱們必需要寫super(),不然會報錯。值得一提的是,必須先調用super,纔可使用this,不然也會報錯

貼一個關於super的教程(原文地址

 

4. 和 react入門 系列裏面是同樣的,都是經過this.state.xx來獲取狀態

 

 

refs

react入門3 裏也介紹了的refs的相關知識,這裏再總結一下。

 

案例5:

react/src/entries/index.js(index.html、index.css和index.less不變)

import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import './index.css'; class Parent extends Component { constructor() { super();
this.state = { val:321 }; } changes(){ this.setState({ val:this.refs.inputs.value }) } render(){ return( <div> <input ref="inputs" value={this.state.val} onChange={this.changes.bind(this)} /> <Child txt={this.state.val} /> </div> ) } } class Child extends Component{ render(){ return( <span> {this.props.txt} </span> ) } } ReactDOM.render( <Parent />, document.getElementById('root') )

效果以下

下面來分析一下

  • 在constructor裏設置val初始值

  •  input裏首先經過this.state.val獲取val的值,當input值發生改變的時候,觸發onChange事件,調用changes方法。這裏ref屬性,就至關於給input取了一個名,叫inputs

  •  在changes裏,經過this.setState從新給val賦值,值爲this.refs.inputs.value。this.refs.inputs就至關於獲取了ref屬性值爲inputs的input;this.refs.inputs.value就至關於獲取了這個input的value值

  • 在子組件Child裏,經過this.props.txt獲取父組件Parent上Child標籤上txt的屬性值,即爲input的value值

 

 

package.json

關於package.json這裏講一下下圖列表的東西都是怎麼來的吧。

看到上面紅色框勾出來的,這裏就以react爲例來說解。

"react": "^15.0.2",冒號前面是名字,冒號後面是版本號。

 

上面列表裏的內容都是怎麼來的呢? 

 

先將上面紅色框勾出來的這一行刪除(以下圖所示)。

在react文件夾下啓動cmd或者git:$ npm install react --save(以下圖所示)

完成以後,就能夠看到,列表裏面又有了react這一行(版本號可能不同,以下圖所示)

當有了上面紅框這一行,就表示你成功了,除了這裏,還能夠在react/node_modules文件夾裏也會找到react這個文件夾,以下圖所示

 

有了react/package.json這個文件,你能夠把react/node_modules文件夾刪除,而後在react文件夾下啓動cmd或者git:$ npm i,以下圖所示

又會從新安裝這些依賴,從新生成node_modules文件夾

 

關於package.json那些列表裏的東西都是作什麼的、怎麼用,你們能夠去npm或者cnpm去查一下

 

 

mock數據

在講解ajax以前,先說一下怎麼mock數據吧

react/src文件夾下新建一個mock文件夾,以下圖所示

react/src/mock文件夾下,新建一個music.json文件,以下圖所示

react/src/mock/music.json 文件內容以下

{
    "success":true,
    "data":[
        {
            "id":1,
            "music":"rock"
        },
        {
            "id":2,
            "music":"pop"
        },
        {
            "id":3,
            "music":"classical"
        }
    ]
}

 

在react文件夾下新建proxy.config.js,以下圖所示

react/proxy.config.js 內容以下

module.exports = {
  '/users': function(req, res) {
      res.json({
        success: true,
        data: [
          {
            "id":1,
            "username":"sam"
          },
          {
            "id":2,
            "username":"amy"
          },
          {
            "id":3,
            "username":"kim"
          }
        ],
      });
  },

  'GET /music': './src/mock/music.json'
};

下面來分析

在這裏我就寫了這兩種mock數據的方式,更多的方法戳這裏去看:規則定義

 

寫到這裏,我順帶粘貼一下個人文件目錄

 

 

ajax

關於ajax,咱們須要藉助別的庫、插件、依賴,例如像jquery、zepto、fetch、superagent等等,能夠去npm搜索一下ajax挑選本身喜歡的一種。

這裏咱們用的是isomorphic-fetchisomorphic-fetch教程),在package.json裏能夠找到,以下圖所示

react/package.json

 

 

案例6:

react/src/entries/index.js(index.html、index.css和index.less不變)

import React, { Component, PropTypes } from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import fetch from 'isomorphic-fetch';

class Parent extends Component {
  componentWillMount(){
    var self = this;
    fetch('/users')
      .then(function(response) {
          if (response.status >= 400) {
              console.log("Bad response from server");
          }
          return response.json();
      })
      .then(function(data) {
          self.setState({users:data.data})
      });
  }

  constructor() {
      super();
      this.state = {
          users:[]
      };
  }

  render(){
    return(
      <ul>
        {
          this.state.users.map(function(user, index){
            return (
              <li key={index}>{user.username}</li>
            )
          })
        }
      </ul>
    )
  }
}

ReactDOM.render(
  <Parent />,
  document.getElementById('root')
)

 在react文件夾下啓動服務器:$ npm start,在瀏覽器打開http://localhost:8989/,效果以下

下面來分析一下

componentWillMount,組件即將加載,這時候能夠用ajax獲取初始化頁面須要用到的數據。

 

下面來分析上面的map循環(在 react入門2 裏有講過map循環),先寫一個for循環作對比

var arr = [1,2,3,4];
for(var i=0;i<arr.length;i++){
   console.log(arr[i])
}

 

固然除了isomorphic-fetch,還有其餘實現ajax的方法,這裏就不講了。

 

此次就講解這麼多,有疑問的地方歡迎你們給我留言~~~

相關文章
相關標籤/搜索