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

資訊專欄INFORMATION COLUMN

淺析 React 生命周期

lansheng228 / 1364人閱讀

摘要:在使用組件的進(jìn)行組件實例化時,得到的便是其返回值。也就是說,如果其子組件的或發(fā)生改變時,只會取決于那個組件的方法的返回值。文章為本人原創(chuàng),原文見本人個博淺析生命周期一淺析生命周期二

Overview

最近常有學(xué)習(xí)React相關(guān)的技術(shù),寫了幾個React的小Demo,使用 React/Express 技術(shù)棧。實在太小,羞于拿出來細(xì)說。React 的確是一個值得追隨的技術(shù)。但React體系實在龐大,我目前僅略知一二。這里要挑出來說的,是React的生命周期機(jī)制。Demo的學(xué)習(xí)過程中,對它的方便、易用之處實在是深有體會,在一些細(xì)節(jié)處也值得斟酌,在這里做一下記錄,便于分享。

如果你接觸過React,大概對rendercomponentWillMount等,會相對的熟悉,因為它們再常用不過。但用歸用,其中的一些理論上的細(xì)節(jié),往往容易在使用的過程中被忽略,使我們多敲了不少代碼,心很累的 : )

通俗來講,React 將組件 component 在web中的形成、修改和渲染等劃分為若干個階段,組成組件的生命周期。在一個完整的生命周期內(nèi),一個組件會經(jīng)過若干個階段,在特殊的階段組件會調(diào)用一個特別的lifecycle method,即生命周期方法。如下:

constructor(props)

componentWillMount()

render()

componentDidMount()

componentWillReceiveProps(nextProps)

shouldComponentUpdate(nextProps, nextState)

componentWillUpdate(nextProps, nextState)

render( )* //理解上與3. render()略有不同,見下。

componentDidUpdate(prevProps, prevState )

componentWillUnmount( )

值得注意,這些生命周期是React 內(nèi)置的,在特定條件下就會被調(diào)用。而開發(fā)者可以做的就是 override(重載)這些方法,以實現(xiàn)想要的功能。

constructor

constructor(props),組件形成時調(diào)用。

constructor 函數(shù)可理解為組件的構(gòu)造函數(shù),從組件的類(class) 實例化一個組件實例。這個函數(shù)在組件形成時被調(diào)用,是所有生命周期函數(shù)中最先執(zhí)行的。在constructor函數(shù)內(nèi),如有必要,進(jìn)行state的初始化以及綁定方法;否則可以省去constructor函數(shù)的聲明。

有以下幾點在開發(fā)時值得注意:

constructor 函數(shù)內(nèi),在執(zhí)行任何statement之前,必須是super() 函數(shù),如果有參數(shù)須將參數(shù)帶上。這點跟Java很像。

在constructor 函數(shù)內(nèi),this.props 返回 undefined

不要在初試化state時引用props 里的值,否則每當(dāng)props更新時,都需要在componentWillReceiveProps 函數(shù)內(nèi)對state進(jìn)行更新。(同時這也涉及到組件state選取的原則,如有需要請閱讀Thinking in React)

class App extends Component {
  constructor(props) {
    super(props);//------------(1)
    console.log(this.props);// undefined ------------(2)
    //initialize the state
    this.state = {
      value: "",
      color: props.initialColor  // 不可取  ------------(3)
    }
    //bind methods
    this.handleClick = this.handleClick.bind(this);
  }
}
componentWillMount

componentWillMount(),在組件首次渲染(render)之前調(diào)用。

mount安裝之意,我們可以理解為組件首次被加載在web中。因此每次頁面加載/刷新,或者某個組件第一次加載進(jìn)入web時可以調(diào)用componentWillMount( ) 函數(shù)。舉個例子,在首次進(jìn)入文章列表時時,可在 componentWillMount 對所有文章進(jìn)行查詢。這樣,在render之前,就能拿到所有文章的數(shù)據(jù),以便在render中使用。

在componentWillMount ( ) 函數(shù)內(nèi),若對this.state進(jìn)行更新,無法觸發(fā)重新渲染組件。

class PostList extends Component {
  //...
  //在componentWillMount 組件內(nèi)獲取所有博客列表
  componentWillMount(){
    axios.get("/posts")
         .then(res=>{
           //...
         });
  }
  //在 render 函數(shù)內(nèi)將拿到的博客列表 渲染在頁面中
  render(){
    //...
  }
}
Render

render()

render 即 渲染函數(shù),是編寫組件代碼時,唯一一個必須的函數(shù)。該函數(shù)須有返回值,返回一個組件,即最終渲染出來的組件。在使用組件的class進(jìn)行組件實例化時,得到的便是其返回值。

返回值有兩種類型:

一個父標(biāo)簽,這個父標(biāo)簽內(nèi)可以包含若干個子標(biāo)簽,在最外層標(biāo)簽必須只有一個。

false 或者 null,代表不渲染任何DOM

class App extends Component {
  //...
  render(){
    return (
      
//...
) } }

注意:在render函數(shù)中只做與返回組件相關(guān)的工作,勿在其中對state進(jìn)行操作,可以保證每次調(diào)用render函數(shù),返回的組件都是相同的。否則將加大項目維護(hù)成本。

另外,如果shouldComponentUpdate函數(shù)返回false,則不執(zhí)行render函數(shù)。關(guān)于shouldComponentUpdate將在下面介紹。

componentDidMount

componentDidMount(),一旦組件首次加載完成,便會調(diào)用

如果需要對渲染出來的DOM節(jié)點做任何操作,可以在此處進(jìn)行。(提示: this.refs 可獲取真實DOM)。

在該組件內(nèi)設(shè)置state將會導(dǎo)致組件被重新渲染。

class App extends Component {
  //..
  componentDidMount(){
    //將會觸發(fā)組件重新渲染
    this.setState({
      value: "100"
    }):
    //對節(jié)點進(jìn)行操作
      this.refs.div.appendChild(newChild);
  }
  
}

上面對 React生命周期函數(shù)中的constructor / componentWillMount / render / componentDidMount 四個函數(shù)進(jìn)行了介紹。下面將繼續(xù)介紹另外5個方法。在此之前,先總結(jié)一下,下面列表中列出的3.render()8.render()的在邏輯上的區(qū)別和聯(lián)系。先上一個列表。

constructor(props)

componentWillMount( )

render( )

componentDidMount( )

componentWillReceiveProps(nextProps)

shouldComponentUpdate(nextProps, nextState)

componentWillUpdate(nextProps, nextState)

render()*

componentDidUpdate(prevProps, prevState)

componentWillUnmount()

「兩個」render( )方法的區(qū)別

3.render( ) 與 8.render( )*

實質(zhì)上,這兩個方法毫無區(qū)別。但這里為什么要提及它們之間的區(qū)別呢?其實,它們只是同一函數(shù) render( ) 在組件生命周期的兩個不同階段的不同理解而已。

前一個 render( ) 方法指在組件第一次被加載進(jìn)入頁面時,調(diào)用的 render( ) 方法;后一個則指除去第一次,之后調(diào)用的 render( ) 方法。

因此,我們更愿意稱第一次的 render( ) 方法為 mount( 安裝 ),稱后一個 render( ) 方法為 re-render ( 重新渲染 ) 。這也是為什么組件首次 render 前后的方法名中帶有mount一詞的緣故了。

這是 React 的伎倆,或者設(shè)計哲學(xué)吧。怎么認(rèn)為都行,我認(rèn)為很有趣?

下面介紹的方法,都是圍繞第二個 render( ) ,即重新渲染 re-render 展開的。

componentWillReceiveProps

componentWillReceiveProps(nextprops),已加載的組件在 props 發(fā)生變化時調(diào)用。

如果需要通過監(jiān)聽 props 的改變來修改 state 的值,則可以通過重載該函數(shù)實現(xiàn)。

需要注意,在有些情況下,組件的 props 未發(fā)生改變也會調(diào)用該函數(shù)。因此如果在該函數(shù)內(nèi)的邏輯,只是想捕獲當(dāng)前 props 與 接收的 nextProps 的不同來做出一些操作,則最好先將 props 與 nextProps 進(jìn)行比較。

1.在mounting階段,即首次 render ,不調(diào)用 componentWillReceiveProps 方法。理解了兩個 render( ) 的不同,便知道這里是為什么了。

2.this.setState({…}) 不觸發(fā) componentWillReceiveProps 方法。因為該方法只監(jiān)聽 this.props 的改變,不關(guān)心 this.state 值的變化。

class App extends Component {
  componentWillReceiveProps(nextProps){
    //接收的顏色 與 當(dāng)前顏色不同時
    if (this.props.color !== nextProps.color){
      ...
    }
  }
}
shouldComponentUpdate

shouldComponentUpdate(nextProps, nextState)

返回 true orfalse

要不要更新(重新渲染)組件?淺顯易懂。這個方法的返回值決定了,當(dāng) props 或者 state 值發(fā)生變化時,組件是否重新渲染。兩種情況:

返回true,重新渲染。緊接著,繼續(xù)執(zhí)行 componentWillUpdate()render()componentDidUpdate()

false,不重新渲染。不再執(zhí)行任何生命周期函數(shù)函數(shù)(亦不執(zhí)行該組件的 render( ) 函數(shù))。但是,并不妨礙其子組件。也就是說,如果其子組件的 props 或 state 發(fā)生改變時,只會取決于那個組件的 shouleComponentUpdate ( ) 方法的返回值。道理雖懂,但遇到是可能會犯迷糊,因為開發(fā)中常常會遇見組件嵌套的情況,父子組件之間傳遞同一套 props 或 state,一來二去,誰更新誰不更新,容易迷糊,需要仔細(xì)咯。

在絕大部分情況下,當(dāng) props 或 state 改變時,都是需要重新渲染組件的。

注意,根據(jù) React 官方 的說法,就算 shouldComponentUpdate( ) 方法返回 false,組件也會重新渲染。需要隨時注意官方文檔的變化。

class PostList extends Component {
  shouldComponentUpdate(nextProps, nextState){
    //return true;默認(rèn)
    return false;// 不更新組件
  }
}
componentWillUpdate

componentWillUpdate(nextProps, nextState),當(dāng) shouldComponentUpdate( ) 方法返回 true 后調(diào)用。

這個方法提供了一個為重新渲染作準(zhǔn)備的機(jī)會,意思是要在這里,趁接下來的 render( ) 方法重新渲染之前,完成該完成的操作。這個方法在 mount 階段不會被調(diào)用,只在 re-render 階段被調(diào)用。

注意,不要在該方法內(nèi)調(diào)用 this.setState({…}),如有需要,請在 componentWillReceiveProps( ) 方法中完成。養(yǎng)成良好的編程規(guī)范。

class App extends Component {
  componentWillUpdate(nextProps, nextState){
    var isLate = this.nextProps.isLate;
    if(isLate){
      //...
    } else {
      //...
    }
  }
}
componentDidUpdate

componentDidUpdate(prevProps, preState),一旦組件首次更新(重新渲染)完成時調(diào)用。

因此像 componentDidMount( ) 一樣,如果需要對渲染出來的DOM節(jié)點做任何操作,可以在此處進(jìn)行。(提示: this.refs 可獲取真實DOM)。

在該組件內(nèi)設(shè)置state將會導(dǎo)致組件被重新渲染。

class App extends Component {
  //..
  componentDidUpdate(){
    //將會觸發(fā)組件重新渲染
    this.setState({
      value: "100"
    });
    //對節(jié)點進(jìn)行操作
    this.refs.div.appendChild(newChild);
  }
  
}
componentWillUnmount

componentWillUnmount(),在組件即將被卸載(或銷毀)之前調(diào)用。

在這個方法中,適合做一些清理善后工作。例如清楚timer,取消網(wǎng)絡(luò)請求,或者清除在 componentDidMount 或 componentDidUpdate 中生成的相關(guān) DOM 節(jié)點。

總結(jié)

mountre-render 的是有區(qū)別的。

mount階段使用前一部分的四個方法( constructor / componentWillMount / render / componentDidMount),圍繞組件首次加載而調(diào)用;

后一部分 re-render 相關(guān)的,使用 componentWillReceiveProps / shouldComponentUpdate / componentWillUpdate / render / componentDidUpdate ,圍繞組件重新渲染而調(diào)用。

我總結(jié)了一張流程圖和一個表格,以表示這些周期函數(shù)之間的關(guān)系,以及在何種情況下會調(diào)用這些函數(shù)。

注意:componentWillUnmount 方法未包含其中。

mount props 變化 state 變化
constructor componentWillReceiveProps shouldComponentUpdate
componentWillMount shouldComponentUpdate (return true) ? / 結(jié)束
render (return true) ? / 結(jié)束 componentWillUpdate
componentDidMount componentWillUpdate render
/ render componentDidUpdate
/ componentDidUpdate /

完。

文章為本人原創(chuàng),原文見本人個博:
淺析「React」生命周期(一)
淺析「React」生命周期(二)

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/81485.html

相關(guān)文章

  • React-生命周期雜記

    摘要:前言自從發(fā)布之后,更新速度日新月異,而生命周期也隨之改變,雖然原有的一些生命周期函數(shù)面臨廢棄,但理解其背后更新的機(jī)制也是一種學(xué)習(xí)在這里根據(jù)官方文檔以及社區(qū)上其他優(yōu)秀的文章進(jìn)行一個對于生命周期的總結(jié),大致上分為以下三個模塊新老生命周期的區(qū)別為 前言 自從React發(fā)布Fiber之后,更新速度日新月異,而生命周期也隨之改變,雖然原有的一些生命周期函數(shù)面臨廢棄,但理解其背后更新的機(jī)制也是一種...

    KoreyLee 評論0 收藏0
  • 【V8引擎】淺析Chrome V8引擎中的垃圾回收機(jī)制和內(nèi)存泄露優(yōu)化策略

    摘要:一前言的垃圾回收機(jī)制使用垃圾回收機(jī)制來自動管理內(nèi)存。垃圾回收器只會針對新生代內(nèi)存區(qū)老生代指針區(qū)以及老生代數(shù)據(jù)區(qū)進(jìn)行垃圾回收。分別對新生代和老生代使用不同的垃圾回收算法來提升垃圾回收的效率。 V8 實現(xiàn)了準(zhǔn)確式 GC,GC 算法采用了分代式垃圾回收機(jī)制。因此,V8 將內(nèi)存(堆)分為新生代和老生代兩部分。 一、前言 V8的垃圾回收機(jī)制:JavaScript使用垃圾回收機(jī)制來自動管理內(nèi)存。垃...

    qingshanli1988 評論0 收藏0
  • 庫,組件,框架 - 收藏集 - 掘金

    摘要:哈哈,我理解,架構(gòu)就是骨架,如下圖所示譯年月個有趣的和庫前端掘金我們創(chuàng)辦的使命是讓你及時的了解開發(fā)中最新最酷的趨勢。 翻譯 | 上手 Webpack ? 這篇就夠了! - 掘金譯者:小 boy (滬江前端開發(fā)工程師) 本文原創(chuàng),轉(zhuǎn)載請注明作者及出處。 原文地址:https://www.smashingmagazine.... JavaSrip... 讀 Zepto 源碼之代碼結(jié)構(gòu) - ...

    tommego 評論0 收藏0
  • 2017-06-13 前端日報

    摘要:前端日報點關(guān)注,不迷路精選前端團(tuán)隊工作流遷移記譯新語法私有屬性知乎專欄前端每周清單大前端技術(shù)生命周期模型發(fā)布面向生產(chǎn)環(huán)境的前端性能優(yōu)化模塊實現(xiàn)入門淺析知乎專欄中文一個線下沙龍中國最大的前端技術(shù)社區(qū)單頁面博客從前端到后端基于 2017-06-13 前端日報 點關(guān)注,不迷路:-P 精選 ESLint v4.0.0 released - ESLint - Pluggable JavaScri...

    曹金海 評論0 收藏0

發(fā)表評論

0條評論

lansheng228

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<