成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

react 生命周期

Fundebug / 1955人閱讀

摘要:一個組件的生命周期分為三個部分實例化存在期和銷毀時。如果回調(diào)函數(shù)以函數(shù)的方式來指定,那么在組件更新的時候回調(diào)會被調(diào)用次。

一個React組件的生命周期分為三個部分:實例化、存在期和銷毀時。

實例化階段

客戶端渲染時,如下依次被調(diào)用

getDefaultProps()

getInitialState()

componentWillMount()

render()

componentDidMount()

服務(wù)端渲染

getDefaultProps()

getInitialState()

componentWillMount()

render()

注意:componentDidMount()不會再服務(wù)端被渲染;

getDefaultProps

對于每個組件實例來講,這個方法只會調(diào)用一次,該組件類的所有后續(xù)應(yīng)用,getDefaultPops 將不會再被調(diào)用,其返回的對象可以用于設(shè)置默認的props值。

var Hello = React.creatClass({
    getDefaultProps: function(){
        return {
            name: "pomy",
            git: "dwqs"
        }
    },
    
    render: function(){
        return (
            
Hello,{this.props.name},git username is {this.props.dwqs}
) } }); ReactDOM.render(, document.body);

也可以在掛載組件的時候設(shè)置 props。

var data = [{title: "Hello"}];

或者調(diào)用 setProps (一般不需要調(diào)用)來設(shè)置其 props

var data = [{title: "Hello"}];
var Hello = React.render(, document.body);
Hello.setProps({data:data});

但只能在子組件或組件樹上調(diào)用 setProps。別調(diào)用 this.setProps 或者 直接修改 this.props。將其當做只讀數(shù)據(jù)。

React通過 propTypes 提供了一種驗證 props 的方式,propTypes 是一個配置對象,用于定義屬性類型:

var survey = React.createClass({
    propTypes: {
        survey: React.PropTypes.shape({
            id: React.PropTypes.number.isRequired
        }).isRequired,
        onClick: React.PropTypes.func,
        name: React.PropTypes.string,
        score: React.PropTypes.array
        ...
    },
    
    //...
})

或者

import React, { Component } from "react"
import PropTypes from "prop-types"

class BetterImage extends Component{...}

BetterImage.PropTypes={
  src: PropTypes.string,
  center: PropTypes.bool,
  loadingImage: PropTypes.string,
  defaultImage: PropTypes.string,
  onLoad: PropTypes.func,
  onError: PropTypes.func,
  onComplete: PropTypes.func
}
BetterImage.defaultProps={
  ....
}

getInitialState

對于組件的每個實例來說,這個方法的調(diào)用有且只有一次,用來初始化每個實例的 state,在這個方法里,可以訪問組件的 props。每一個React組件都有自己的 state,其與 props 的區(qū)別在于 state只存在組件的內(nèi)部,props 在所有實例中共享。

getInitialState 和 getDefaultPops 的調(diào)用是有區(qū)別的,getDefaultPops 是對于組件類來說只調(diào)用一次,后續(xù)該類的應(yīng)用都不會被調(diào)用,而 getInitialState 是對于每個組件實例來講都會調(diào)用,并且只調(diào)一次。

var LikeButton = React.createClass({
  //初始化State
  getInitialState: function() {
    return {liked: false};
  },
  
  handleClick: function(event) {
    //設(shè)置修改State
    this.setState({liked: !this.state.liked});
  },

  render: function() {
    var text = this.state.liked ? "like" : "haven"t liked";
    return (
      

You {text} this. Click to toggle.

); } }); ReactDOM.render( , document.getElementById("example") );

每次修改 state,都會重新渲染組件,實例化后通過 state 更新組件,會依次調(diào)用下列方法:

1、shouldComponentUpdate
2、componentWillUpdate
3、render
4、componentDidUpdate

componentWillMount

在渲染前調(diào)用,在客戶端也在服務(wù)端。React 官方正式發(fā)布了 v16.3 版本。在這次的更新中,除了前段時間被熱烈討論的新 Context API 之外,新引入的兩個生命周期函數(shù) getDerivedStateFromProps,getSnapshotBeforeUpdate 以及在未來 v17.0 版本中即將被移除的三個生命周期函數(shù) componentWillMount,componentWillReceiveProps,componentWillUpdate .

在這個生命周期中你會遇到一下問題:

a.首屏無數(shù)據(jù)導致白屏
在 React 應(yīng)用中,許多開發(fā)者為了避免第一次渲染時頁面因為沒有獲取到異步數(shù)據(jù)導致的白屏,而將數(shù)據(jù)請求部分的代碼放在了 componentWillMount 中,希望可以避免白屏并提早異步請求的發(fā)送時間。但事實上在 componentWillMount 執(zhí)行后,第一次渲染就已經(jīng)開始了,所以如果在 componentWillMount 執(zhí)行時還沒有獲取到異步數(shù)據(jù)的話,頁面首次渲染時也仍然會處于沒有異步數(shù)據(jù)的狀態(tài)。換句話說,組件在首次渲染時總是會處于沒有異步數(shù)據(jù)的狀態(tài),所以不論在哪里發(fā)送數(shù)據(jù)請求,都無法直接解決這一問題。而關(guān)于提早發(fā)送數(shù)據(jù)請求,官方也鼓勵將數(shù)據(jù)請求部分的代碼放在組件的 constructor 中,而不是 componentWillMount。
若是為了改善用戶體驗曾經(jīng)用過的解決方法有兩個:

方法一:異步請求組件,使用nprogress 添加加載動畫;

import React, { Component } from "react"
import NProgress from "nprogress"
import "nprogress/nprogress.css"
import "./customNprogress.styl"

NProgress.configure({ showSpinner: false })

export default function asyncComponent(importComponent) {
  class AsyncComponent extends Component {
    state = {
      component: null
    }

    async componentDidMount() {
      NProgress.start()
      const { default: component } = await importComponent()
      NProgress.done()

      this.setState({ component })
    }

    render() {
      const C = this.state.component

      return C ?  : null
    }
  }

  return AsyncComponent
}

const AsyncNotFound = asyncComponent(() => import(/* webpackChunkName: "NotFound" */ "@/routes/NotFound"))

方法二:使用 onreadystatechange 去監(jiān)聽 readyState,在資源加載完成之前加載一個只有框架的靜態(tài)頁面,頁面不請求數(shù)據(jù)。當數(shù)據(jù)請求完成之后再將路由切換到真實的首頁。

  function listen () {
    if (document.readyState == "complete") { // 資源加載完成
        ReactDom.render(
            
                
                    
                
            ,
            document.getElementById("root")
        )
    } else { // 資源加載中
        ReactDom.render(
            
                
                    
                
            ,
            document.getElementById("root")
        )
    }
}

document.onreadystatechange = listen

具體參考解決React首屏加載白屏的問題

b.事件訂閱

另一個常見的用例是在 componentWillMount 中訂閱事件,并在 componentWillUnmount 中取消掉相應(yīng)的事件訂閱。但事實上 React 并不能夠保證在 componentWillMount 被調(diào)用后,同一組件的 componentWillUnmount 也一定會被調(diào)用。一個當前版本的例子如服務(wù)端渲染時,componentWillUnmount 是不會在服務(wù)端被調(diào)用的,所以在 componentWillMount 中訂閱事件就會直接導致服務(wù)端的內(nèi)存泄漏。另一方面,在未來 React 開啟異步渲染模式后,在 componentWillMount 被調(diào)用之后,組件的渲染也很有可能會被其他的事務(wù)所打斷,導致 componentWillUnmount 不會被調(diào)用。而 **componentDidMount 就不存在這個問題,在 componentDidMount 被調(diào)用后,componentWillUnmount 一定會隨后被調(diào)用到,并根據(jù)具體代碼清除掉組件中存在的事件訂閱。**

render

該方法會創(chuàng)建一個虛擬DOM,用來表示組件的輸出。對于一個組件來講,render方法是唯一一個必需的方法。render方法需要滿足下面幾點:

只能通過 this.props 和 this.state 訪問數(shù)據(jù)(不能修改)

可以返回 null,false(這種場景下,react渲染一個

閱讀需要支付1元查看
<