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

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

關(guān)于state的理解

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

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

  3. state是組件實(shí)例的屬性,函數(shù)組件沒有實(shí)例,因?yàn)楹瘮?shù)組件沒有狀態(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é)構(gòu)獲取state中的數(shù)據(jù)
    // let {flag,firstMsg, lastMsg} = this.state;

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

3) 更新狀態(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"))

示例說明:

  1. setState每次修改內(nèi)容會(huì)自動(dòng)觸發(fā)React重新渲染頁面
  2. 因此示例中每次點(diǎn)擊都會(huì)修改狀態(tài),更加狀態(tài)重新渲染內(nèi)容,達(dá)到內(nèi)容切換的目的
2.3 狀態(tài)的簡寫定義
2.3.1 說明:
  1. ES6 class類中 constructor 函數(shù)為構(gòu)造函數(shù), 內(nèi)部通過this定義的屬性是類實(shí)例的屬性
  2. class類中其他的方法確實(shí)實(shí)例原型上的方法
  3. 但是class類中的表達(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
*/

示例說明:

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

因此我們?nèi)绻牒唽憇tate的定義,就可以如下定義:

示例代碼:

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 說明
  1. 不知道有沒有人這么思考過, 函數(shù)組件沒有狀態(tài)
  2. 我們是否可以使用變量來模擬狀態(tài)的概念呢
  3. 好像狀態(tài)也就是一個(gè)數(shù)據(jù), 定義的變量來存儲(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>
    )
}

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

示例說明:

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

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

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

示例說明:

  1. React.render渲染函數(shù)封裝在render函數(shù)中
  2. 每次修改數(shù)據(jù)完畢后,手動(dòng)的調(diào)用render函數(shù),重新渲染頁面
  3. 因此大多數(shù)情況下回選擇使用state狀態(tài)
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末双吆,一起剝皮案震驚了整個(gè)濱河市褂微,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌产阱,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,607評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡默辨,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,239評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門苍息,熙熙樓的掌柜王于貴愁眉苦臉地迎上來缩幸,“玉大人,你說我怎么就攤上這事竞思”硪辏” “怎么了?”我有些...
    開封第一講書人閱讀 164,960評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵衙四,是天一觀的道長铃肯。 經(jīng)常有香客問我,道長传蹈,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,750評(píng)論 1 294
  • 正文 為了忘掉前任步藕,我火速辦了婚禮惦界,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘咙冗。我一直安慰自己沾歪,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,764評(píng)論 6 392
  • 文/花漫 我一把揭開白布雾消。 她就那樣靜靜地躺著灾搏,像睡著了一般。 火紅的嫁衣襯著肌膚如雪立润。 梳的紋絲不亂的頭發(fā)上狂窑,一...
    開封第一講書人閱讀 51,604評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音桑腮,去河邊找鬼泉哈。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的丛晦。 我是一名探鬼主播奕纫,決...
    沈念sama閱讀 40,347評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼烫沙!你這毒婦竟也來了匹层?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,253評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤锌蓄,失蹤者是張志新(化名)和其女友劉穎又固,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體煤率,經(jīng)...
    沈念sama閱讀 45,702評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡仰冠,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,893評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了蝶糯。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片洋只。...
    茶點(diǎn)故事閱讀 40,015評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖昼捍,靈堂內(nèi)的尸體忽然破棺而出识虚,到底是詐尸還是另有隱情,我是刑警寧澤妒茬,帶...
    沈念sama閱讀 35,734評(píng)論 5 346
  • 正文 年R本政府宣布担锤,位于F島的核電站,受9級(jí)特大地震影響乍钻,放射性物質(zhì)發(fā)生泄漏肛循。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,352評(píng)論 3 330
  • 文/蒙蒙 一银择、第九天 我趴在偏房一處隱蔽的房頂上張望多糠。 院中可真熱鬧,春花似錦浩考、人聲如沸夹孔。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,934評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽搭伤。三九已至,卻和暖如春袜瞬,著一層夾襖步出監(jiān)牢的瞬間怜俐,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,052評(píng)論 1 270
  • 我被黑心中介騙來泰國打工吞滞, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留佑菩,地道東北人盾沫。 一個(gè)月前我還...
    沈念sama閱讀 48,216評(píng)論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像殿漠,于是被迫代替她去往敵國和親赴精。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,969評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容