手挽手帶你學React:一檔 React環境搭建,語法規則,基礎使用

手挽手帶你學React入門第一期,帶你熟悉React的語法規則,消除對JSX的恐懼感,因爲如今開發中都是使用ES6語法開發React,因此此次也使用ES6的模式進行教學,若是你們對ES6不熟悉的話,先去看看class相關內容吧,這裏我也慢慢帶你們一步一步學會React。javascript

視頻教程

視頻教程可移步個人我的博客:http://www.henrongyi.tophtml

什麼是React

React是Facebook的一羣變態們開發的一個特別牛X的框架。它其實是一個虛擬DOM,而後在這個DOM中,要用什麼組件就能飛速加載進來,不要的時候,立刻給刪咯(實際上就是個前端框架,都是這麼個意思,VUE,NG都是,只不過他們的數據流向不一樣而已,React區別就在於,單向數據流。),React 扮演着 MVC 結構中 V 的角色,後面我會用到基於FLUX架構的Redux讓咱們的整個項目變成MVC架構。總之,React也是hie牛X的。前端

React的好處都有啥

React是一款很是牛X的前端框架,它的衍生物React-Native可讓你開發接近原生體驗的NativeApp,它適合的範圍至關普遍,前端,後端,手機端,都有很好的兼容性。總而言之,hie牛X。vue

React基礎入門

如今的開發中React項目實際上都是使用ES6語法來編寫,而且,咱們如今有不少成熟的腳手架可使用(create-react-app,dva等),不過國際慣例,咱們要從最基礎的用法開始編寫。咱們採用ES6寫法來進行教學,同時使用webpack工具,這裏會用到不少相關配置,你們能夠在這個過程當中體驗ES6的精妙。java

開始HelloWord

配置基礎webpack環境react

這裏你們能夠不去深刻理解,先跟着我一步一步配置出來webpack

開始以前,你們能夠去官網:https://reactjs.org/ 下載最新的React(當前版本v16.7.0) 中文地址:https://react.docschina.org/ git

因爲咱們不使用腳手架,因此咱們須要先建立咱們本身的webpack包,第一步es6

mkdir helloReact
cd helloReact

首先你們命令行輸入github

webpack v

若是正常出現版本號 而且是 3.6.0版本,那麼咱們就能夠按照教程繼續走下去了
若是沒有的話 那麼咱們就須要命令行繼續

cnpm i webpack@3.6.0 -S -g

到這裏應該能夠正常使用webpack了

接下來 咱們命令行輸入

npm init -y  // 這其實是 初始化一個項目 而且所有默認 固然若是你想看看裏面有啥的話 就把-y拿掉就行了
npm i  //這裏是把webpack依賴安裝到本包內部
npm i webpack-dev-server@2.11.1 --save-dev //安裝本地運行服務器
npm i webpack-cli --save-dev //依賴腳手架

運行完成之後,咱們會獲得一個package.json文件 打開看看

{
  "dependencies": {
    "webpack": "^3.6.0"  //依賴包和版本
  },
  "name": "helloreact", //項目名
  "version": "1.0.0",  // 版本號
  "main": "index.js",  //入口文件
  "scripts": {  //npm run 加這裏面的key就能夠快速執行命令行
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",  // 做者
  "license": "ISC",
  "description": "" //簡介
}

這裏面其實是咱們項目的一些基礎信息

咱們須要本身配置webpack和babel 這裏咱們須要建立兩個文件
這裏面咱們要設置入口文件,輸出文件,babel,webpackServer等等,這裏不作太詳細的介紹 你們能夠直接複製代碼,後面可能會開專門的webpack視頻課程。
小小的介紹一下這些都是幹什麼用的

babel-core 調用Babel的API進行轉碼
babel-loader
babel-preset-es2015 用於解析 ES6
babel-preset-react 用於解析 JSX
babel-preset-stage-0 用於解析 ES7 提案

命令行輸入

npm install --save-dev babel-core babel-loader@7.1.5 babel-preset-es2015 babel-preset-react babel-preset-stage-0

接下來咱們在helloReact 文件夾中建立 webpack.config.js 文件

// webpack.config.js 直接複製便可 
const path = require("path");
module.exports = {
   /*入口*/
   entry: path.join(__dirname, 'src/index.js'),
    
   /*輸出到dist文件夾,輸出文件名字爲bundle.js*/
   output: {
       path: path.join(__dirname, './dist'),
       filename: 'bundle.js'
   },
    /*src文件夾下面的以.js結尾的文件,要使用babel解析*/
    /*cacheDirectory是用來緩存編譯結果,下次編譯加速*/
    module: {
        rules: [{
            test: /\.js$/,
            use: ['babel-loader?cacheDirectory=true'],
            include: path.join(__dirname, 'src')
        }]
    },
    plugins : [],
    devServer : {
        disableHostCheck: true,
        inline: true,
        port:9527,
        contentBase: path.join(__dirname, "/"),
    }
}

接下來咱們在helloReact 文件夾中建立 .babelrc 文件

{
    "presets": [
      "es2015",
      "react",
      "stage-0"
    ],
    "plugins": []
  }

而後咱們在package.json文件的script中添加

//package.json
{
  "dependencies": {
    "webpack": "^3.6.0"
  },
  "name": "helloreact",
  "version": "1.0.0",
  "main": "index.js",
  "scripts": {
    "server": "webpack-dev-server",
    "build": "webpack",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "description": "",
  "devDependencies": {
    "babel-core": "^6.26.3",
    "babel-loader": "^7.1.5",
    "babel-preset-es2015": "^6.24.1",
    "babel-preset-react": "^6.24.1",
    "babel-preset-stage-0": "^6.24.1",
    "webpack-cli": "^3.1.2",
    "webpack-dev-server": "^2.11.1"
  }
}

這些配置完了,咱們就在helloReact mkdir src 而且在src中建立 index.js文件
在 根路徑 helloReact下建立 index.html
由於這裏咱們要用到 react了 因此須要命令行安裝一下 react

cnpm install --save react react-dom

html文件以下

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <div id="app"></div>
</body>
<script src="bundle.js"></script>
</html>

js 文件以下

import React from 'react';  //es6 引入react
import ReactDom from 'react-dom'; //es6 引入reactReacrDom

ReactDom.render(  //ReactDom渲染<div>hello React</div> 這個html標籤 到 id='app'這個標籤下
    <div>Hello React!</div>, document.getElementById('app'));

一切都寫完了 咱們運行服務 npm run server 來看一眼

若是你看到屏幕顯示出 Hello React! 那麼恭喜你 環境配置完了 我們能夠開始學習 React 了

若是你配置了半天還沒配置成功

到個人github下載代碼吧。。。https://github.com/piexlmax/h...

React的Hello World

咱們看到上面的代碼

import React from 'react';  //es6 引入react
import ReactDom from 'react-dom'; //es6 引入reactReacrDom

ReactDom.render(  //ReactDom渲染<div>hello React</div> 這個html標籤 到 id='app'這個標籤下
    <div>Hello React!</div>, document.getElementById('app'));

這是一個簡單的渲染 是否是根本看不到 React的組件化模式呢?

因此這裏 咱們須要寫一個根部組件,之後的組件都放跟組件裏面,這個JS就理所固然成了一個入口文件了

這裏 咱們在 src下面建立一個app.js文件

app.js

import React, {Component} from 'react';
// 這裏咱們引入 react 和 react的Component 
// 建立 Hello 這個class(class屬於ES6內容) 而後繼承 Component 咱們就成功地建立了一個 react組件

export default class App extends Component {
    render() {
        return (
            <div>
                Hello,World!
            </div>
        )
    }
}

index.js 咱們須要改寫爲這樣

import React from 'react';
import ReactDom from 'react-dom';

import App from './app.js'  //引入咱們的根組件App
ReactDom.render( //把App 渲染到 id=app的dom中
    <App/>, document.getElementById('app'));

到這裏 咱們已經實現了一個真正意義上的Hello World了!

傳說中的jsx

開始玩React了,那就必需要用到jsx語法,什麼是jsx呢?

JSX是一種JavaScript的語法擴展。JSX與模板語言類似,但它具備JavaScript的所有功能。JSX會被編譯爲React.createElement()方法調用,將返回名爲「React elements」的普通JavaScript對象。

上面代碼裏咱們看到 咱們的html其實是在js中的render函數中書寫的,是一個React擴展,容許咱們編寫看起來像 HTML的JavaScript 。

切記 自定義組件必定要大寫字母開頭 return加括號 而且左括號要和return在同一行 只能return一個標籤,其他內容都要在這個標籤內部

export default class App extends Component {
    render() {
        return (
            <div>
                Hello,World!
            </div>
        )
    }
}

像是這樣一段代碼,實際上咱們真正使用的時候,已經通過了一次編譯,編譯事後它長這樣。

export default class App extends React.Component {
  render() {
    return (
      React.createElement(
        'div',
        'Hello,World!'
      )
    );
  }
}

下面的這一段代碼是否是就不容易理解了?這其實是js能夠幫咱們去書寫dom的代碼。
在React中JSX你能夠理解爲咱們能夠在js中寫HTML代碼了 更通俗一點

export default class App extends Component {
    // 方法 生命週期 state 等
    render() {
        return (
        //    HTML模板
        )
    }
}

React的基本使用方法

state

咱們以前學過VUE,VUE中每一個組件的數據存在本身的data中,那麼在React中,數據存在哪裏呢?沒錯狀態state中。
因爲咱們這裏用的是ES6的class 因此 咱們子類constructor中必須先調用super才能引用this。
因此咱們這裏應該這麼寫state

export default class App extends Component {
    constructor(){
        super()
        this.state={
            hello:"hello World"
        }
    }
    render() {
        return (
            <div>
                {this.state.hello}
            </div>
        )
    }
}

這裏咱們能夠看出,咱們想要在render中使用js 就須要用一個{} 這裏面的內容一樣能夠書寫簡單的js表達式。

rander函數中使用state和JS表達式

export default class App extends Component {
    constructor(){
        super()
        this.state={
            hello:"hello World"
        }
    }
    render() {
        return (
            <div>
                <ul>
                    <li>展現state中的數據:{this.state.hello}</li>
                    <li>三元,短路等,這裏用三元示例{this.state.hello?"存在hello":"不存在hello"}</li>
                    <li>簡單計算{1+1}</li>
                    <li>JS表達式{Math.floor(Math.random()*10)}</li>
                </ul>
            </div>
        )
    }
}

方法的聲明以及修改state

聲名方法咱們有兩種模式,一種是直接書寫 方法名(參數){代碼段}模式,這樣的模式在調用的時候須要手動bind(this)
還有一種就是使用es6的箭頭函數,讓其this指向自身

修改state數據須要調用 this.setState()方法 內部接收一個對象 要修改哪一個key 就在對象內部填寫這個key,而且後面的值就是你要修改的內容,若是,key在state中不存在,則會在state中增長這個key

export default class App extends Component {
    constructor(){
        super()
        this.state={
            hello:"hello World"
        }
    }
    bye(){
        this.setState({
            hello:"bye world"
        })
    }
    byebye=()=>{
        this.setState({
            helloo:"bye world"
        })
    }
    render() {
        return (
            <div>
                <ul>
                    <li>非箭頭函數:{this.state.hello}</li>
                    <li>箭頭函數:{this.state.helloo}</li>
                </ul>
                <button onClick={this.bye.bind(this)}>無箭頭</button>  
                {/* 這裏使用bind來綁定this 若是傳參的話this.bye.bind(this,參數1,參數2) */} 
                <button onClick={()=>{this.byebye()}}>箭頭函數</button>
                 {/* 這裏是箭頭函數的默認屬性來搞定了this問題 若是傳參的話()=>{this.byebye(參數1,參數2)*/}}
            </div>
        )
    }
}

這裏須要注意,只有觸發了state的變化,纔會致使組件的從新渲染

循環語句,條件語句的使用

你們在vue中使用v-for 就可以完成循環生成組件這樣的操做了,在react中咱們應該怎麼作呢?

循環語句
咱們說過 jsx 裏面是能夠自由自在地使用js的 通常狀況下咱們使用map循環

在循環的時候,每個return出來的標籤都須要添加 key={鍵值} 「鍵值」是建立元素數組時須要包含的特殊字符串屬性。鍵值能夠幫助React識別哪些元素被更改,添加或刪除。所以你應當給數組中的每個元素賦予一個肯定的標識

export default class App extends Component {
    constructor(){
        super()
        this.state={
            arr:[{text:"qm"},{text:"奇淼"},{text:"大帥逼"}]
        }
    }
    
    render() {
        return (
            <div>
            {/* 咱們說過 jsx 裏面是能夠自由自在地使用js的 這裏咱們來玩一個循環生成li */}
                <ul>
                   {this.state.arr.map((item,key)=>{
                       return(<li key={key}>{item.text}</li>)
                   })}
                </ul>
            </div>
        )
    }
}

判斷語句
判斷語句咱們通常使用短路表達式 三元表達式來展現咱們想要展現的內容,可是若是須要複雜的條件判斷,那麼咱們最好是寫一個自執行函數,而後再函數體內你就能夠隨心所欲了,記住必定要return你想要獲得的dom標籤。

export default class App extends Component {
    constructor(){
        super()
        this.state={
            arr:[{text:"qm"},{text:"奇淼"},{text:"大帥逼"}]
        }
    }
    
    render() {
        return (
            <div>
            {/*簡單的三元和短路實例*/}
            {this.state.arr.length==3?<div>我是三元判斷的三個</div>:<div>我是三元判斷的不是三個</div>}
            {this.state.arr.length==3&&<div>我是短路判斷的三個</div>}
            {/* 咱們說過 jsx 內部支持簡單的表達式 若是咱們使用 if條件句的話 會致使報錯*/}
                {/*
                    if(this.state.arr.length==3){
                        return(<div>有三個</div>)
                    }
                */}
            {/* 咱們說過 jsx 這已是js代碼段而不是簡單語句了,咱們簡單判斷可使用三元或者短路表達式來進行,可是複雜一點的,咱們可使用以下方法*/}
            {(()=>{
                if(this.state.arr.length==3){
                    return(<div>數組有三個元素</div>)
                }else{
                    return(<div>數組有不是三個元素</div>)
                }
            })()}
            </div>
        )
    }
}

循環判斷嵌套
有些時候咱們須要根據特定條件去循環,而後渲染出篩選事後的數據,這時候就須要循環和判斷嵌套使用了,其實也至關簡單,咱們的循環其實是一個簡單的js表達式,內部的function中能夠隨意書寫js,記得return就行了

export default class App extends Component {
    constructor(){
        super()
        this.state={
            arr:[{text:"qm"},{text:"奇淼"},{text:"大帥逼"}]
        }
    }
    
    render() {
        return (
            <div>
                {this.state.arr.map((item,key)=>{
                    if(key%2==0){
                        return(<div key={key}>我是能夠餘2的{item.text}</div>)
                    }else{
                        return(<div key={key}>我是不能餘2的{item.text}</div>)
                    }
                })}
            </div>
        )
    }
}

獲取DOM(Refs)

有些時候咱們不得不去操做DOM,那這時候 咱們須要用到 ref 屬性

React支持一個能夠附加到任何組件的特殊屬性ref。ref屬性能夠是一個字符串或一個回調函數。當ref屬性是一個回調函數時,函數接收底層DOM元素或類實例(取決於元素的類型)做爲參數。這使你能夠直接訪問DOM元素或組件實例。

另外這裏應該注意 不要過分使用 Refs。

export default class App extends Component {
    constructor(){
        super()
        this.state={
            arr:[{text:"qm"},{text:"奇淼"},{text:"大帥逼"}]
        }
    }
    
    render() {
        return (
            <div>
                {this.state.arr.map((item,key)=>{
                    if(key%2==0){
                        return(<div ref="link" key={key}>我是能夠餘2的{item.text}</div>)
                        {/* 這樣咱們能夠經過 this.refs.link 獲取到這個dom 而且操做dom了 */}
                    }else{
                        return(<div key={key}>我是不能餘2的{item.text}</div>)
                    }
                })}
            </div>
        )
    }
}

總結

到這裏咱們已經學會了React的基本組件內部的操做了,React相對於Vue來講更加靈活,可是惟一的缺點是數據流是單向的,必須經過setState來修改,對於處理表單來講會有些麻煩,不過有些UI框架,插件幫咱們處理了這些大麻煩。寫寫玩玩吧React仍是比較簡單的。

相關文章
相關標籤/搜索