第四節(jié):React組件狀態(tài)的State屬性

1. State狀態(tài)理解

關(guān)于state的理解

  1. state 是組件對(duì)象中最重要的屬性,值是對(duì)象(可以包含多個(gè)數(shù)據(jù))

  2. 組件被稱(chēng)為"狀態(tài)機(jī)",通過(guò)更新組件的state來(lái)更新對(duì)應(yīng)的頁(yè)面顯示(重新渲染組件)

  3. state是組件實(shí)例的屬性,函數(shù)組件沒(méi)有實(shí)例,因?yàn)楹瘮?shù)組件沒(méi)有狀態(tài)

  4. state可以理解是組件自己的數(shù)據(jù), props數(shù)據(jù)是外部傳入,state數(shù)據(jù)就是組件自己的

2. State狀態(tài)的使用

2.1 state使用規(guī)則
  1. state 通常在組件的constructor中進(jìn)行初始化

  2. state 只能用setState方法更新

  3. setState會(huì)導(dǎo)致render重新執(zhí)行,渲染組件和所有的子組件

1) 初始化狀態(tài)
constructor(props){
    super(props)

    // 定義state狀態(tài)
    this.state = {
        flag: true,
        firstMsg: "天王蓋地虎",
        lastMsg : "小雞燉蘑菇"
    }
}

2) 讀取某個(gè)狀態(tài)值
render(){
    let flag = this.state.flag;
    let firstMsg = this.state.firstMsg;
    let lastMsg = this.state.lastMsg;

    // 簡(jiǎn)寫(xiě)方式: 結(jié)構(gòu)獲取state中的數(shù)據(jù)
    // let {flag,firstMsg, lastMsg} = this.state;

    return (
      <div> { flag ? firstMsg :lastMsg}</div>
    )
  }

3) 更新?tīng)顟B(tài) --> 組件界面更新
this.setState({
    stateProp1: value1,
    stateProp2: value2
})

2.2 示例代碼:
class MyCom extends React.Component{
    constructor(props){
        super(props);

        // 定義state狀態(tài)
        this.state = {
            flag: true,
            firstMsg: "天王蓋地虎",
            lastMsg : "小雞燉蘑菇"
        }
    }

    changeFlag = () => {

        // 修改state狀態(tài)數(shù)據(jù)
        this.setState({
            // 取出狀態(tài)取反,然后改變狀態(tài)
            flag : !this.state.flag
        })
    }

    render(){
        // let flag = this.state.flag;
        // let firstMsg = this.state.firstMsg;
        // let lastMsg = this.state.lastMsg;

        let {flag,firstMsg, lastMsg} = this.state;

        return (
            <div onClick={ this.changeFlag }> { flag ? firstMsg :lastMsg}</div>
        )
    }
}

ReactDOM.render(<MyCom/>, document.getElementById("app"))

示例說(shuō)明:

  1. setState每次修改內(nèi)容會(huì)自動(dòng)觸發(fā)React重新渲染頁(yè)面
  2. 因此示例中每次點(diǎn)擊都會(huì)修改狀態(tài),更加狀態(tài)重新渲染內(nèi)容,達(dá)到內(nèi)容切換的目的
2.3 狀態(tài)的簡(jiǎn)寫(xiě)定義
2.3.1 說(shuō)明:
  1. ES6 class類(lèi)中 constructor 函數(shù)為構(gòu)造函數(shù), 內(nèi)部通過(guò)this定義的屬性是類(lèi)實(shí)例的屬性
  2. class類(lèi)中其他的方法確實(shí)實(shí)例原型上的方法
  3. 但是class類(lèi)中的表達(dá)式定義的內(nèi)容確實(shí)實(shí)例上的內(nèi)容
2.3.2 示例
class Person{
    constructor(){
        // 實(shí)例屬性
        this.name = "張三"
    }

    // 實(shí)例上的屬性
    age = 18

    // 實(shí)例上的方法
    eat = function(){
        console.log("eat")
    }

    // 原型上的方法
    run(){
        console.log("eat")
    }
}

var xm = new Person
console.log(xm)

/*
打印結(jié)果:
    Person {age: 18, name: "張三", eat: ?}
        age: 18
        eat: ? ()
        name: "張三"
        __proto__:
            constructor: class Person
            run: ? run()
            __proto__: Object
*/

示例說(shuō)明:

  1. ES6中class類(lèi)里定義的表達(dá)式,無(wú)論是函數(shù)表達(dá)式,函數(shù)普通的表達(dá)式,最后都是實(shí)例的屬性或方法
  2. ES6中class類(lèi)中普通定義的函數(shù)是實(shí)例原型上的方法

因此我們?nèi)绻牒?jiǎn)寫(xiě)state的定義,就可以如下定義:

示例代碼:

class MyCom extends React.Component{
    constructor(props){
        super(props);

    }

    // 初始化定義state狀態(tài)
    state = {
        flag: true,
        firstMsg: "天王蓋地虎",
        lastMsg : "小雞燉蘑菇"
    }

   // 組件實(shí)例化上的方法
    changeFlag = () => {

        // 修改state狀態(tài)數(shù)據(jù)
        this.setState({
            // 取出狀態(tài)取反,然后改變狀態(tài)
            flag : !this.state.flag
        })
    }

    render(){

        let {flag,firstMsg, lastMsg} = this.state;

        return (
            <div onClick={ this.changeFlag }> { flag ? firstMsg :lastMsg}</div>
        )
    }
}

ReactDOM.render(<MyCom/>, document.getElementById("app"))

3. 關(guān)于函數(shù)組件

3.1 說(shuō)明
  1. 不知道有沒(méi)有人這么思考過(guò), 函數(shù)組件沒(méi)有狀態(tài)
  2. 我們是否可以使用變量來(lái)模擬狀態(tài)的概念呢
  3. 好像狀態(tài)也就是一個(gè)數(shù)據(jù), 定義的變量來(lái)存儲(chǔ)數(shù)據(jù)是否可以
3.2 示例代碼:
// 定義數(shù)據(jù)
let state = {
    flag: true,
    firstMsg: "天王蓋地虎",
    lastMsg : "小雞燉蘑菇"
}

function MyCom(){
    // 獲取數(shù)據(jù)
    let {flag,firstMsg, lastMsg} = state;

    // 修改數(shù)據(jù)函數(shù)
    let changeFlag = () => {
        console.log(11);
        // 11
        state.flag = !state.flag
    }

    // 返回react元素
    return (
        <div onClick={ changeFlag }> { flag ? firstMsg :lastMsg}</div>
    )
}

// 頁(yè)面渲染
ReactDOM.render(<MyCom/>, document.getElementById("app"))

示例說(shuō)明:

  1. 當(dāng)每次點(diǎn)擊的時(shí)候,控制臺(tái)會(huì)打印11說(shuō)明事件沒(méi)有任何問(wèn)題
  2. 每次點(diǎn)擊過(guò)后,在控制臺(tái)打印state數(shù)據(jù),會(huì)發(fā)現(xiàn)flag的值發(fā)生了變化
  3. 可以頁(yè)面卻并沒(méi)有任何變化
  4. 原因在于普通變量數(shù)據(jù)的變化并不會(huì)觸發(fā)react重新渲染頁(yè)面,但state會(huì)
  5. 如果真的希望頁(yè)面重繪,就需要封裝渲染函數(shù),手動(dòng)觸發(fā)
3.3 封裝渲染函數(shù)

修改示例代碼如下:

function MyCom(){
    let {flag,firstMsg, lastMsg} = state;

    let changeFlag = () => {
        console.log(11);

        state.flag = !state.flag

        // 每次flag值發(fā)生改變,重新渲染頁(yè)面
        render()
    }

    return (
        <div onClick={ changeFlag }> { flag ? firstMsg :lastMsg}</div>
    )
}

// 封裝頁(yè)面渲染函數(shù)
function render(){
    ReactDOM.render(<MyCom/>, document.getElementById("app"))
}
// 初始渲染一次
render()

示例說(shuō)明:

  1. React.render渲染函數(shù)封裝在render函數(shù)中
  2. 每次修改數(shù)據(jù)完畢后,手動(dòng)的調(diào)用render函數(shù),重新渲染頁(yè)面
  3. 因此大多數(shù)情況下回選擇使用state狀態(tài)
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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