成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

React精髓!一篇全概括(急速)

daryl / 1502人閱讀

摘要:即組件內(nèi)部可以引用其他組件,如注意在中,組件必須返回單一的根元素,這也是為什么組件中需要用標(biāo)簽包裹的原因。那么,這種情況下,為我們提供了生命周期的鉤子函數(shù),方便我們進行使用。

一個人并不是生來要給打敗的,你盡可以把他消滅掉,可就是打不敗他。? ? ?

學(xué)和使用react有一年多了,最近想在梳理一下react基礎(chǔ)知識,夯實基礎(chǔ),激流勇進~ 關(guān)于reacr-router,redux,redux-saga后續(xù)都會慢慢輸出,希望各位看官老爺持續(xù)關(guān)注~~要是能給個贊鼓勵一下就更了~

提醒一下: 看完之后抓緊時間趁熱打鐵,redux,react-redux,redux-saga

一篇文章總結(jié)redux、react-redux、redux-saga

react基礎(chǔ)知識速覽 1、什么是JSX?

一個JSX語法的示例,如下所示

const element = 

Hello, world!

;

這種語法形式,既不是HTML,也不是字符串,而是稱之為JSX,是React里用來描述UI和樣式的語法,JSX最終會被編譯為合法的JS語句調(diào)用(編譯器在遇到{時采用JS語法進行解析,遇到<就采用HTML規(guī)則進行解析)

2、嵌入表達(dá)式

JSX中,可以使用花括號{}嵌入任意的JavaScript合法表達(dá)式,如:2 + 2、user.firstNameformatName(user)都是合法的。示例如:

const user = {
    firstName: "Zhang",
    lastName : "Busong"
};

const elem = (
    

Hello, {formatName(user)}

); /* 這里的(),實際上是可選的,但是React推薦加入(),這樣子就會被視為一個表達(dá)式,而不會導(dǎo)致 自動插入分號的問題 */ ReactDOM.render( element, document.getElementById("app") )
3、JSX也是一種表達(dá)式

JSX本身也是一種表達(dá)式,所以它可以像其他表達(dá)式一樣,用于給一個變量賦值、作為函數(shù)實參、作為函數(shù)返回值,等等。如:

function getGreeting(user) {
    if (user) {
        return 

Hello, {formatName(user)}

} return

Hello, Guest!

; }

注意: 1、在JSX中,聲明屬性時不要使用引號,如果聲明屬性的時候使用引號,那么將被作為字符串解析,而不會被作為一個表達(dá)式解析,如:

"{user.firstName}" lastName={user.lastName}>

解析后,可以得到:

"{user.firstName}" lastName="Lau">

因此,當(dāng)我們需要使用一個字符串字面量的時候,可以使用引號,但是如果要作為表達(dá)式解析的時候,則不應(yīng)當(dāng)使用引號 2、在JSX中,有些屬性名稱需要進行特殊處理。如class應(yīng)該用className代替,tabindex則用tabIndex代替。這是因為JSX本質(zhì)上更接近于JavaScript,而class是JavaScript中的保留字。同時,應(yīng)該使用camelCase來命名一個屬性,而不是使用HTML的屬性命名方式 3、JSX本身已經(jīng)做了防注入處理,對于那些不是明確編寫的HTML代碼,是不會被解析為HTML DOM的,ReactDOM會將他們一律視為字符串,在渲染完成前就轉(zhuǎn)化為字符串,所以可以防止XSS攻擊 4、如果JSX標(biāo)簽是閉合的,那么結(jié)尾需要用/>,另外,JSX標(biāo)簽是可以互相嵌套的,這和HTML里是一樣的

4、JSX實質(zhì)

JSX通過babel編譯,而babel實際上把JSX編譯給React.createElement()調(diào)用。如下JSX代碼:

const element = (
    

"greeting"> Hello, world!

);

是等同于以下的語句的:

const elem = React.createElement(
    "h1",
    {className: "greeting"},
    "Hello, world!"
);

React.createElement()方法會首先進行一些避免BUG的檢查,然后返回類似以下例子的對象:

const element = {
    type: "h1",
    props: {
        className: "greeting",
        children: "Hello, world"
    }
}

這樣的對象,則稱為React元素,代表所有呈現(xiàn)在屏幕上的東西。React正是通過讀取這些對象來構(gòu)建DOM,并且保持?jǐn)?shù)據(jù)和UI同步的

5、元素渲染

元素(elements)是構(gòu)成React應(yīng)用的最小單元,元素描述了想要在屏幕中看到的內(nèi)容,如:

const element = 

Hello, world

;

和DOM元素不同的是,React元素是純對象,創(chuàng)建的代價低。并且React會進行優(yōu)化處理,只把有必要的變化更新到DOM上。此外,元素和組件的概念,是不一樣的,組件是由元素組成的。

6、將元素渲染進DOM

在React中,使用ReactDOM.render()方法來將React元素渲染進一個DOM中。如:

ReactDOM.render(
    element,
    document.getElementById("root")
)

React元素是不可變的,所以一旦一個元素創(chuàng)建完成后,我們是無法改變其內(nèi)容或者屬性的。一個元素就像是動畫里的一幀,它代表UI在某一時間點的樣子。如果非要使用元素來構(gòu)成可變化的UI界面,就需要使用setInterval了,如:

function tick() {
    const element = (
        
Now is {new Date().toLocaleTimeString()}
); ReactDOM.render( element, document.getElementById("root") ); } setInterval(tick, 1000);

在實際開發(fā)中,大多數(shù)React應(yīng)用只會調(diào)用一次ReactDOM.render(),所以更好的方式是使用有狀態(tài)組件

7、組件和Props

組件(component)能夠?qū)I劃分為獨立的、可復(fù)用的部分,這樣我們就只需專注于構(gòu)建每一個多帶帶的部件。 從概念上看,組件就像是函數(shù):接受任意的輸入(稱為屬性,Props),返回React元素。React中有兩種定義組件的方式:函數(shù)定義類定義

1、函數(shù)定義組件

這種方式是最簡單的定義組件的方式,就像寫一個JS函數(shù)一樣,如:

function Welcome (props) {
    return 

Hello, {props.name}

;; }
2、類定義組件

還可以使用ES6里的類來定義一個組件,如下所示:

class Welcome extends React.Component {
    render () {
        return 

Hello, {this.props.name}

; } }

這種方式比起函數(shù)定義方式則更加靈活

3、組件渲染

先前,我們遇到的React元素只是呈現(xiàn)一個DOM標(biāo)簽,如:

const element = 

然而,React元素也可以是用戶自定義的組件,如:

const element = "Tom" />

Welcome組件中聲明了一個屬性name="Tom",而這個屬性,將以props.name的方式傳遞給組件,如下方式:

function Welcome (props) {
    return 

Hello, {props.name}

; }

此時,對于以下的代碼:

ReactDOM.render(
    "張不慫" />,
    document.getElementById("root")
)

最終就會以

Hello, 張不慫

的方式呈現(xiàn)。在這個過程中,發(fā)生了如下的事情:

元素調(diào)用了ReactDOM.render()豐富

React將{ name: "張不慫" }作為props實參來調(diào)用Welcome組件

Welcome完成渲染,返回

Hello, 張不慫

元素

ReactDOM計算最小更新代價,然后更新DOM

4、組合組件

組件是可以組合的。即組件內(nèi)部可以引用其他組件,如:

function Welcome (props) {
    return 

Hello, {props.name}

; } function App () { return (
"Tom" /> "Jack" /> "Mike" />
) } ReactDOM.render( , document.getElementById("root") )

注意: 在React中,組件必須返回單一的根元素,這也是為什么App組件中需要用

標(biāo)簽包裹的原因。如以下的方式,是錯誤的(因為它有3個根元素):

function App () {
    return (
        "Tom" />
        "Jack" />
        "Mike" />
    )
}
5、屬性是只讀的

考慮以下這種情況:

function sum (a, b) {
    return a + b;
}

這種函數(shù)稱為純函數(shù):它不改變自己的輸入值,且總是對相同的輸入返回相同的結(jié)果。 與之對立的,則是非純函數(shù),如:

function withdraw (account, amount) {
    account.total -= amount;
}

非純函數(shù)在函數(shù)內(nèi)改變了輸入的參數(shù)。在React中,無論是通過function還是class聲明組件,我們都不應(yīng)該修改它自身的屬性(props)。雖然React相當(dāng)靈活,但是它也有一個嚴(yán)格的規(guī)定:所有的React組件都必須像純函數(shù)那樣來使用它們的props

8、State與生命周期

使用類定義組件有一些額外的好處,如擁有本地狀態(tài)這一特性。 以下是一個類定義組件

class Clock extends React.Component {
    render () {
        return (
            

Hello, world!

Now is {this.props.date.toLocaleTimeString()}

); } }

需要注意的有:

類名即為組件名(無論是函數(shù)定義組件還是類定義組件,組件名稱的首字母都必須大寫,并且繼承自React.Component

使用 render() 方法,用來返回需要呈現(xiàn)的內(nèi)容

1、在類中加入state

state是屬于一個組件自身的。我們可以在類的構(gòu)造函數(shù)constructor中來初始化狀態(tài),如:

constructor (props) {
    super(props)
    this.state = {
        date: new Date()
    }
}

如此一來,我們就可以在render()函數(shù)中使用this.state.xxx來引用一個狀態(tài)

2、生命周期

在應(yīng)用里,往往都會有許許多多的組件。在組件銷毀后,回收和釋放它們所占據(jù)的資源非常重要。 在時鐘應(yīng)用的例子里,我們需要在第一次渲染到DOM的時候設(shè)置一個定時器,并且需要在相應(yīng)的DOM銷毀后,清除這個定時器。那么,這種情況下,React為我們提供了生命周期的鉤子函數(shù),方便我們進行使用。在React中,生命周期分為: 1)Mount 已插入真實DOM 2)Update 正在重新渲染 3)Unmount 已移出真實DOM 而相應(yīng)的,生命周期鉤子函數(shù)有:

componentWillMount

componentDidMount

componentWillUpdate(newProps, nextState)

componentDidUpdate(prevProps, prevState)

componentWillUnmount()

此外,還有兩種特殊狀態(tài)的處理函數(shù):

componentWillReceiveProps(nextProps) 已加載的組件收到新的參數(shù)時調(diào)動

shouldComponentUpdate(nextProps, nextState) 組件判斷是否重新渲染時調(diào)用

因此,基于生命周期鉤子函數(shù),我們可以實現(xiàn)一個時鐘應(yīng)用如下:

class Clock extends React.Component {
    constructor (props) {
        super(props);
        this.state = {
            date: new Date()
        }
    }
    tick () {
        this.setState({
            date: new Date()
        });
    }
    componentDidMount () {
        this.timerId = setInterval(() => {
            this.tick()
        }, 1000);
    }
    componentWillUnmount () {
        clearInterval(this.timerId);
    }
    render () {
        return (
            
Now is {this.state.date.toLocaleTimeString()}
); } }

需要注意的是: 1)render()里用不到的state,不應(yīng)該聲明在state里 2)不能直接使用this.state.xxx = xxx的方式來改變一個state的值,應(yīng)該使用this.setState()。如:

setName () {
    this.setState({
        name: "張不慫"
    })
}

this.setState()會自動覆蓋this.state里相應(yīng)的屬性,并觸發(fā)render()重新渲染。 3)狀態(tài)更新可能是異步的 React可以將多個setState()調(diào)用合并成一個調(diào)用來提升性能。且由于this.propsthis.state可能是異步更新的,所以不應(yīng)該依靠它們的值來計算下一個狀態(tài)。這種情況下,可以給setState傳入一個函數(shù),如:

this.setState((prevState, props) => ({
    counter: prevState.counter + props.increment
}));
9、事件處理

React元素的事件與DOM元素類似,不過也有一些區(qū)別,如: 1)React事件使用camelCase命名(onClick),而不是全小寫的形式(onclick) 2)使用JSX,傳入的是事件的句柄,而不是一個字符串 如以下的HTML:


使用React的方式描述如:


還有一個不同在于,在原生DOM中,我們可以通過返回false來阻止默認(rèn)行為,但是這在React中是行不通的,在React中需要明確使用preventDefault()來阻止默認(rèn)行為。如:

function ActionLink () {
    function handleClick (e) {
        e.preventDefault();
        alert("Hello, world!");
    }

    return (
        "#" onClick={handleClick}>Click Me
    );
}

這里,事件回調(diào)函數(shù)里的event是經(jīng)過React特殊處理過的(遵循W3C標(biāo)準(zhǔn)),所以我們可以放心地使用它,而不用擔(dān)心跨瀏覽器的兼容性問題。 注意: 在使用事件回調(diào)函數(shù)的時候,我們需要特別注意this的指向問題,因為在React里,除了構(gòu)造函數(shù)和生命周期鉤子函數(shù)里會自動綁定this為當(dāng)前組件外,其他的都不會自動綁定this的指向為當(dāng)前組件,因此需要我們自己注意好this的綁定問題, 通常而言,在一個類方式聲明的組件里使用事件回調(diào),我們需要在組件的constructor里綁定回調(diào)方法的this指向,如:

class Counter extends React.Component {
    constructor (props) {
        super(props);
        this.state = {
            counter: 0
        }
        // 在這里綁定指向
        this.increment = this.increment.bind(this);
    }
    increment () {
        this.setState({
            counter: this.state.counter + 1
        });
    }
    render () {
        return (
            
The counter now is: {this.state.counter}
); } }

當(dāng)然,我們還有另外一種方法來使用箭頭函數(shù)綁定指向,就是使用實驗性的屬性初始化語法,如:

class Counter extends React.Component {
    increment: () => {
        this.setState({
            counter: this.state.counter + 1
        });
    }
    // ...
}

3)像事件處理程序傳遞參數(shù) 我們可以為事件處理程序傳遞額外的參數(shù),方式有以下兩種:




需要注意的是,使用箭頭函數(shù)的情況下,參數(shù)e要顯式傳遞,而使用bind的情況下,則無需顯式傳遞(參數(shù)e會作為最后一個參數(shù)傳遞給事件處理程序)

10、條件渲染

在React里,我們可以創(chuàng)建不同的組件來封裝我們需要的功能。我們也可以根據(jù)組件的狀態(tài),只渲染組件中的一部分內(nèi)容,而條件渲染就是為此而準(zhǔn)備的。在React中,我們可以像在JavaScript中寫條件語句一樣地寫條件渲染語句,如:

function Greet(props) {
    const isLogined = props.isLogined;
    if (isLogined) {
        return 
Hello !
; } return
Please sign in
; } ReactDOM.render( true} />, document.getElementById("root") );

這將渲染出:

Hello !
1、使用變量來存儲元素

我們也可以使用變量來存儲元素,如:

function LogBtn(props) {
    var button;
    const isLogined = props.isLogined;
    if (isLogined) {
        button = 
    } else {
        button = 
    }
    return 
You can {button}
; } ReactDOM.render( false} />, document.getElementById("root") );
2、使用&&運算符進行渲染

由于JavaScript語法對待&&運算符的性質(zhì),我們也可以使用&&運算符來完成條件渲染,如:

function LogBtn(props) {
    var button;
    const isLogined = props.isLogined;
    return (
        
Hello {!isLogined && ( )}
) }

當(dāng)props.isLogined為false的時候,就會渲染出:

Hello
3、使用三目運算符進行渲染

我們可能已經(jīng)發(fā)現(xiàn)了,其實JSX可以像一個表達(dá)式那樣子靈活使用,所以,我們自然也可以使用三目運算符進行渲染,如:

function LogBtn (props) {
    const isLogined = props.isLogined;
    return (
        
You can
) }
4、阻止整個組件的渲染

有時候,我們希望是整個組件都不渲染,而不僅僅是局部不渲染,那么這種情況下,我們就可以在render()函數(shù)里返回一個null,來實現(xiàn)我們想要的效果,如:

function LogBtn (props) {
    const isLogined = props.isLogined;
    const isShow = props.isShow;
    if (isShow) {
        return (
            
You can
) } return null; }

注意: 組件里返回null不會影響組件生命周期的觸發(fā),如componentWillUpdatecomponentDidUpdate仍然會被調(diào)用

11、列表渲染與keys

在JavaScript中,我們可以使用map()函數(shù)來對一個數(shù)組列表進行操作,如:

const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map(number => number*2);
console.log(doubled); // 得到[2, 4, 6, 8, 10]

同樣的,在React里,我們也可以使用map()來進行列表渲染,如:

const numbers = [1, 2, 3, 4, 5];
const listItems = numbers.map(number => {
    return (
        
  • {number}
  • ) }); ReactDOM.render(
      {listItems}
    , document.getElementById("root") )

    這將得到:

    • 1
    • 2
    • 3
    • 4
    • 5

    當(dāng)然,我們還可以進行更好的封裝,如:

    function NumberList (props) {
        const numbers = props.numbers;
        const listItems = numbers.map(number => {
            return (
                
  • {number}
  • ) }); return
      {listItems}
    }

    當(dāng)我們運行以上的代碼的時候,會發(fā)現(xiàn)控制臺提示:Each child in an array or iterator should have a unique "key" prop,因此,我們需要為列表項的每一個項分配一個key,來解決這個問題,通常而言,我們可以使用以下幾種方式來提供key

    使用數(shù)據(jù)項自身的ID,如

  • 使用索引下標(biāo)(index),如:

    const listItems = numbers.map((number, index) => {
        
  • {number}
  • });

    但是React不推薦在需要重新排序的列表里使用索引下標(biāo),因為會導(dǎo)致變得很慢。

    注意: 只有在一個項的同胞里區(qū)分彼此的時候,才需要使用到key,key不需要全局唯一,只需要在一個數(shù)組內(nèi)部區(qū)分彼此時唯一便可。key的作用是給React一個提示,而不會傳遞給組件。如果我們在組件內(nèi)需要同樣的一個值,可以換個名字傳遞,如:

    const content = posts.map(post => (
        
    ));
    
    
    12、表單

    表單和其他的React中的DOM元素有所不同,因為表單元素生來就是為了保存一些內(nèi)部狀態(tài)。在React中,表單和HTML中的表單略有不同

    1、受控組件

    HTML中,、的形式,而是寫成