React 語法基本使用介紹

前面的文章我們已經(jīng)配置好了環(huán)境,接下來熟悉一下 react 的基礎語法:

一、認識入口文件

React 中,app/main.js 叫做入口文件,這個文件是 webpack.congifg.js 的 entry 標識的文件。任何項目入口文件只能有 1 個。

入口文件寫法:

import React from "react";
import ReactDom from "react-dom";
import App from "./App";

ReactDom.render(
    <App />,
    document.querySelector("#app")
);

React 庫就是 React 核心庫,ReactDOM 庫專門用于入口文件,調(diào)用ReactDOM.render() 方法 ,負責將根組件上樹。

引入React 的作用,是因為 React 使用了 jsx 語法,jsx 語法簡單理解就是不加引號的 HTML 語法裸寫在 JS 文件里面,jsx 是英語 JavaScript Extension(JavaScript增強版)的意思,自稱是世界上將 HTML 和 JS 融合的最好的語言。jsx 語法會被 babel 翻譯為字符串拼接。但是,React 規(guī)定,一個有 jsx 語法的 js 文件,必須引入 React 包,否則babel 不予翻譯。

根組件上樹的語法:
ReactDOM.render(JSX , 掛載點);

二、初識組件

組件(component):將頁面中的一部分區(qū)域的 HTML 結(jié)構、CSS 樣式、交互效果、數(shù)據(jù)等進行封裝,封裝到獨立的一個文件中開發(fā),叫做組件。

React 中組件是類,定義一個繼承 React.Component 類的類,就是一個組件。
React 規(guī)定,所有的組件都是一個類,首字母必須嚴格大寫。

在 app 文件夾中創(chuàng)建 App.js,然后書寫標準的類的“殼子”:

import React,{Component} from "react";
export default class App extends Component {
    // 構造函數(shù)
    constructor(){
        //必須調(diào)用超類(父類)
        super();
    }
    render(){
        return (
            <div>
                <h1>我是 App.js 根組件,早上好!</h1>
            </div>
        );
    }
}

類的名字盡可能和文件的名字一樣。

官方手冊上對 render 函數(shù)的描述:The render method returns a description of what you want to see on the screen. In particular, render returns a React element, which is a lightweight description of what to render. Most React developers use a special syntax called “JSX” which makes these structures easier to write.
翻譯:render函數(shù)返回了你想要在屏幕上呈現(xiàn)的東西。一般來說,render 函數(shù)要 return一個 React 元素,這個元素描述了組件長什么樣子。絕大部分 React 的開發(fā)者,使用了一個叫做 JSX 的語法讓結(jié)構更易于書寫。

return 后面直接跟的是 jsx 語法,沒有任何的引號的 HTML。注意不能在 return 后面換行的,因為換行就默認 return undefined 了。如果你非要換行必須像我一樣在上面加個圓括號在圓括號里面換行。

定義完一個類之后,其他的 js 文件就能夠引入它,然后使用它的名字當做標簽名,從而使用實例化這個類:
import App from "./App";

所以使用組件非常簡單:① 引包 ② 變成標簽對 或 單標簽
每當我們寫了一個組件的標簽對之后,就相當于實例化了一次。

三、JSX 語法

JSX 是 facebook 公司為了 React 專門打造的語言,并且已經(jīng)申請了專利,JSX 確實好用。JSX = JavaScript Extension,也有說法叫做 JavaScript + XML。

專門解決 JavaScript 和 HTML 結(jié)合的問題。因為我們原來經(jīng)常寫:

"<div>我愛你" + year + "年</div>"

JSX 徹底解決了這個問題。

<div>我愛你{year}年</div>

  • JSX 要求標簽嚴格封閉,尤其是單標簽,單標簽必須寫末尾反斜杠,比如:
//img 的路徑以 index.html 文件為準
<img />
<br />

必須這么寫,要不然報大錯。

  • 表格標簽必須添加 tbody 標簽。

  • class 要避諱為變?yōu)?className,因為 class 在 JS 里面是關鍵字。

  • JS 生命之源,單大括號插值語法

可插入語法

  1. JS簡單的計算 <h1>我愛你{5000 * 2}年</h1>
  2. JS 內(nèi)置的函數(shù) <h1>我愛你{parseInt(10000.6)}年</h1>
  3. 插入變量 const year = 10000;<h1>我愛你{year}年</h1>
    注意,變量可以存儲 JSX 語法:
    const a = <span>我愛你<em className="spec">10000</em>年</span>;
  4. 插入函數(shù)的執(zhí)行{sum()} 和 允許插入IIFE。
  5. 插入三元運算符
    <h1>我愛你{3 > 8 ? 9 : 10000}年</h1>
  6. 插入自定義組件{<App><App/>}

不可插入語法

  1. 不能插入 for 循環(huán)
  2. 不能插入if語句
  3. 不能插入while語句
  4. 不能插入函數(shù)的聲明
  5. 不能插入對象
  • src 動態(tài)屬性值
    基本使用請記住 "大包引" ,大括號包住引號。

var star = 0 ;<img src = {`images/${star}.png`} />

  • 行內(nèi)樣式
    口訣:雙大括號,標準JSON,省略 px,屬性駝峰。
    注意:即使不需要將style屬性變動態(tài),也需要寫成這樣,這是規(guī)定。
<p style={{
    "width" : 200,
    "height" : 200,
    "backgroundColor" : "red"
}}></p>
  • 動態(tài)類名
    我們需要安裝一個依賴:

npm install --save classnames

靠布爾值來決定這個類名是否生效:

<p className={classnames({
                    "cur" : true,
                    "pure" : true,
                    "color" : 3 > 8,
                    "red" : 0
                })}>你好</p>
  • JSX 中使用數(shù)組(很關鍵,同時也是難點、重點)

注意: JSX的單大括號中如果出現(xiàn)數(shù)組,數(shù)組會被自動展開。

var arr = ["點絳唇·梅","宋代:朱翌","流水泠泠,斷橋橫路梅枝亞。","雪花飛下,渾似江南畫。","白璧青錢,欲買春無價。","歸來也,風吹平野,一點香隨馬。"];
//================
<ul>
    {arr.map((item,index)=> <li key={index}>{item}</li>)}
</ul>

React 中,JSX 數(shù)組項,每項都必須有獨一無二的 key 屬性。key 簡單來說,react 利用 key 來識別組件,它是一種身份標識標識,就像我們的身份證用來辨識一個人一樣。每個 key 對應一個組件,相同的 key react 認為是同一個組件,這樣后續(xù)相同的 key 對應組件都不會被創(chuàng)建. react 中的 key 屬性,它是一個特殊的屬性,它是出現(xiàn)不是給開發(fā)者用的(例如你為一個組件設置 key 之后不能獲取組件的這個key props),而是給 react 自己用的。
key的使用場景?基本基本就是數(shù)組。
官方:在項目開發(fā)中,key 屬性的使用場景最多的還是由數(shù)組動態(tài)創(chuàng)建的子組件的情況,需要為每個子組件添加唯一的 key 屬性值。
注意:index 作為 key 是一種反模式。
在數(shù)組中生成的每項都要有 key 屬性,并且 key 的值是一個永久且唯一的值,即穩(wěn)定唯一。key 值的唯一是有范圍的,即在數(shù)組生成的同級同類型的組件上要保持唯一,而不是所有組件的 key 都要保持唯一。
了解更多參考博客:React 之 key詳解https://segmentfault.com/a/1190000009149186

對數(shù)組操作用到的最多的兩個 ES 方法,就是上面 Map 和 filter。俗稱:刪 filter 改 Map 。

四、九九乘法表
九九乘法表
render(){
    var arr = [];
    for(let i = 1;i <= 9; i++){
        let temp = [];
        for(let j = 1;j <= i;j++){
            temp.push(<td style={{border:"1px solid #353"}} key = {j}>{i} X {j} = {i*j}</td>)
        }
        arr.push(<tr key = {i}>{temp}</tr>);
    }
    return(
            <div>
                <table style={{
                    borderCollapse:"collapse"
                }}>
                    <tbody>
                        {arr}
                    </tbody>
                </table>
            </div>
        );
}
五、組件的 state、事件監(jiān)聽和 MVVM 模式

我們可以快速感知 React ,從一個小小的計數(shù)器開始一步步熟悉。


計數(shù)器.gif
import React,{Component} from "react";

export default class App extends Component{
    constructor(){
        super();
        this.state = {
            a : 0
        }
    }
    render(){
        return (
            <div>
                <h1>{this.state.a}</h1>
                <button onClick = {()=>{
                    this.setState({
                        a : this.state.a + 1
                    })
                }}>按我加一</button>
                
                <button onClick = {()=>{
                    this.setState({
                        a : this.state.a - 2
                    })
                }}>按我減二</button>
            </div>
            )
    }
}

代碼分析:

  • 組件的 state
    React 規(guī)定,任何實例允許有 state 屬性,表示這個組件實例的數(shù)據(jù)。注意,construtor中 this 表示什么?表示實例,即 state 屬性是組件的實例的屬性。
    注意 state 必須是 state 屬性,不能改名,state 屬性的值必須是對象,不能是字符串、不能是數(shù)組等。在render中,可以使用單大括號,這樣的寫法,顯示出state。
  • setState()
    箭頭函數(shù)中要改變 state 對象的 a 屬性值,此時必須用 setState 函數(shù)進行修改。React 規(guī)定,只有用 setState 來改變 state 界面才能自動更新;千萬注意不能直接用 ++,-- 等一元運算符。
  • 事件監(jiān)聽
    在 2008 年,人們認識到了 HTML、CSS、JS 三層分離。所以我們原生 JS、jQuery 都分離的厲害,很明顯現(xiàn)在我們讓他們耦合在了一起。
    onClick={},這個 {} 中要放一個函數(shù)。注意這個函數(shù)必須是箭頭函數(shù),不能是 function。
六、變體寫法

事件監(jiān)聽直接寫在標簽里面是在是太亂了,可以把事件提取出來,需要注意的是提取出來的事件需要綁定上下文的 this 。

    add(){
        this.setState({
            a : this.state.a + 10
        })
    }
    unadd(){
        this.setState({
            a : this.state.a - 10
        })
    }
    render(){
        return (
            <div>
                <h1>{this.state.a}</h1>
                <button onClick = {this.add.bind(this)}>按我加十</button>
                <button onClick = {this.unadd.bind(this)}>按我減十</button>
            </div>
            )
    }

這種寫法簡潔了,但是不能傳參數(shù),所以可以利用箭頭函數(shù)的特性來規(guī)避這個問題。

import React,{Component} from "react";

export default class App extends Component{
    constructor(){
        super();
        this.state = {
            a : 0
        }
    }
    add(n){
        this.setState({
            a : this.state.a + n
        })
    }
    unadd(m){
        this.setState({
            a : this.state.a - m
        })
    }
    render(){
        return (
            <div>
                <h1>{this.state.a}</h1>
                <button onClick = {()=>{
                    this.add(100);
                }}>按我加一百</button>
                <button onClick = {()=>{
                    this.unadd(100);
                }}>按我減一百</button>
            </div>
            )
    }
}
傳參.gif
七、如何獲取 DOM

無論是 Vue 還是 React 都是數(shù)據(jù)驅(qū)動視圖,因此官方都不建議使用 DOM 操作,但是還是預留了這個 API 那就是 ref。2019-7-31 號的時候即之前的 React還是和 Vue 一樣操作 DOM 基本相同都是使用 String 類型的 Refs 例如:<h1 ref="textInput "></h1> ,你可以通過 this.refs.textInput 來訪問 DOM 節(jié)點。但現(xiàn)在 React 不建議使用它了,因為 string 類型的 refs 存在 一些問題。它已過時并可能會在未來的版本被移除。

存在 一些問題

現(xiàn)在官網(wǎng)建議用:

  • 回調(diào)函數(shù)
  • createRef

需要注意的是節(jié)點的引用可以在 ref 的 current 屬性中被訪問(三點):

  • 當 ref 屬性用于 HTML 元素時,構造函數(shù)中使用 React.createRef() 創(chuàng)建的 ref 接收底層 DOM 元素作為其 current 屬性。
  • 當 ref 屬性用于自定義 class 組件時,ref 對象接收組件的掛載實例作為其 current 屬性。
  • 你不能在函數(shù)組件上使用 ref 屬性,因為他們沒有實例

上面講了函數(shù)沒有實例,那怎么使用 ref 呢。答案是使用 forwardRef 方法。

const refA  = createRef();
function A(props,ref){
    return (
        <div>
            <h1 ref={ref}>i am A</h1>
        </div>
    )
}
A = forwardRef(A);
ReactDOM.render(<div>
    <A ref={refA}></A>
    <button onClick = {()=>{
        console.log(refA.current);//h1標簽
    }}>點擊</button>
</div>, document.getElementById("root"));

forwardRef 會使 A 函數(shù)多出來一個參數(shù) ref ,不使用 forwardRef 方法,函數(shù)是沒有第二個參數(shù)的。從效果來看 forwardRef 方法就是把函數(shù)變成類。refA.current 返回的是 h1 標簽,我們還可以使用 useImperativeHandle 改寫使其返回一個對象,注意?? 16.6.3 版本這個方法叫做 useImperativeMethods 。

function A(props, ref) {
    const inputRef = useRef();
    useImperativeHandle(ref, () => ({
      focus: () => {
        inputRef.current.focus();
      },
      name:"Condor Hero",
      age:19
    }));
    return <input ref={inputRef} />;
}
A = forwardRef(A);

const refA  = createRef();
ReactDOM.render(<div>
    <h4>
        <A ref={refA}></A>
        <button onClick = {()=>{
            console.log(refA.current.name);
            console.log(refA.current);
        }}>點擊</button>
    </h4>
</div>, document.getElementById("root"));
八、MVVM 思想

簡單一句話,數(shù)據(jù)變化,視圖自動變化。實現(xiàn)起來就是使用事件來操作 setState 讓 其內(nèi)部的值發(fā)生改變,視圖自動更新。

來兩個案例體驗一下。第一個調(diào)色板:

雙向數(shù)據(jù)綁定,簡稱雙向綁定,再簡稱雙綁。在 React 中也稱為“受控”(under controlled)。

說一下 ref,在 React 中,任何元素都可以添加 ref 屬性,表示 reference 引用

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

  • 40、React 什么是React?React 是一個用于構建用戶界面的框架(采用的是MVC模式):集中處理VIE...
    萌妹撒閱讀 1,185評論 0 1
  • HTML模版 之后出現(xiàn)的React代碼嵌套入模版中。 1. Hello world 這段代碼將一個一級標題插入到指...
    ryanho84閱讀 6,445評論 0 9
  • 1、什么是react React.js 是一個幫助你構建頁面 UI 的庫。React.js 將幫助我們將界面分成了...
    谷子多閱讀 2,648評論 1 13
  • 最近看了一本關于學習方法論的書,強調(diào)了記筆記和堅持的重要性。這幾天也剛好在學習React,所以我打算每天堅持一篇R...
    gaoer1938閱讀 1,812評論 0 5
  • 3. JSX JSX是對JavaScript語言的一個擴展語法, 用于生產(chǎn)React“元素”,建議在描述UI的時候...
    pixels閱讀 2,979評論 0 24

友情鏈接更多精彩內(nèi)容