0x000 概述
上一章說明了生命周期的概念,本質上就是框架在操作組件的過程中暴露出來的一系列鉤子,我們可以選擇我們需要的鉤子,完成我們自己的業務,以下講的是react v16.3以下的生命周期,v16.3以及以上的版本有所不同
0x001 組件掛載以下是組件掛載的過程中觸發的聲明周期:
class App extends React.Component { constructor(props) { super(props) console.log("constructor", props) } componentWillMount() { console.log("componentWillMount") } componentDidMount() { console.log("componentDidMount") } render() { console.log("render") return0x002 組件更新{Date()}
} componentDidMount() { console.log("componentDidMount") } }
以下是組件更新的時候觸發的生命周期:
class App extends React.Component { constructor() { super() this.state = { date: Date() } setTimeout(() => { this.setState({date: Date()}) }, 3000) } componentWillReceiveProps() { console.log("componentWillReceiveProps") } shouldComponentUpdate() { console.log("shouldComponentUpdate") return true } render() { console.log("render") return{this.state.date}
} componentWillUpdate() { console.log("componentWillUpdate") } componentDidUpdate() { console.log("componentDidUpdate") } }
第一次的render是由組件掛載引起的,而其他的方法則是由setState引起的
以下是由組件卸載的時候觸發的生命周期:
class Content extends React.Component { render(){ console.log("Content::render") return0x004 完整生命周期content
} componentWillUnmount() { console.log("Content::componentWillUnmount") } } class App extends React.Component { constructor() { super() this.state = { show: true } setTimeout(() => { this.setState({show: false}) }, 3000) } render() { console.log("App::render") return ( this.state.show ?: null ) } }
掛載: constructor componentWillMount render componentDidMount 更新: componentWillReceiveProps shouldComponentUpdate componentWillUpdate render componentDidUpdate 卸載: componentWillUnmount 錯誤處理(這里不說): componentDidCatch0x005 聲明周期使用場景
constructor(props):
該方法主要用來初始化state,或者初始化一些資源,可以訪問prop,但是訪問不了 setState,會報錯:Warning: Can"t call setState on a component that is not yet mounted. This is a no-op, but it might indicate a bug in your application. Instead, assign to this.state directly or define a state = {}; class property with the desired state in the App component.
class App extends React.Component { constructor() { super() this.state = { show: true } } render() { return ( this.state.show ?: null ) } }
componentWillMount()
沒啥卵用,可以在這個方法中調用setState(),并且設置的state可以在本次渲染生效,推薦使用constructor
render()
你懂的,每次更新狀態都會觸發,但是不要在這里調用會觸發組件更新的函數,比如setState(),否則可能陷入無盡阿鼻地獄。
componentDidMount()
這個方法常用,觸發這個生命周期,意味著dom和子組件都掛載好了,refs也可以用了,一般在這兒做網絡請求。
componentWillReceiveProps(nextProps)
這個組件也常用,一般用于父組件狀態更新,導致傳遞給子組件的props更新,當時子組件又不是直接綁定父組件的props的時候使用,比如
class Content extends React.Component { constructor(props) { super(props) this.state = { content: props.content } } render() { return this.state.content } } class App extends React.Component { constructor() { super() this.state = { content: "1" } setTimeout(() => { this.setState({ content: 10 }) }, 1000) } render() { return () } }
我們接受父組件的state.content作為子組件的初始化state.content,但是1s 之后,父組件發生了變化,state.content從1變成了10,我們期望子組件也同時更新,可惜子組件的constructor只會執行一次,為了解決這個問題,我們可以添加這個生命周期:
class Content extends React.Component { constructor(props) { super(props) this.state = { content: props.content } } componentWillReceiveProps(nextProps) { this.setState({ content:nextProps.content }) } render() { return this.state.content } }
這樣就可已在父組件props更新的時候,觸發子組件的更新
shouldComponentUpdate(nextProps, nextState)
這個組件也很常用,用來判斷是否要進行某次更新,如果返回true則執行更新,如果返回false則不更新,常用與性能優化
class A extends React.Component { render() { console.log("A::render") return "A" } } class B extends React.Component { render() { console.log("B::render") return "A" } } class App extends React.Component { constructor(props) { super(props) this.state = { num: 1 } setTimeout(() => { this.setState({ num: 10, name: 1 }) }) } render() { console.log("App::render") return } } ReactDom.render(, document.getElementById("app") )
我們在App組件中掛載了A、B組件,App綁定了state.num,A、B綁定了state.name,然后在1s 后觸發app組件的更新,此時查看瀏覽器,可以看到,APP、A、B都執行了render,但其實A、B依賴的name并沒有發生改變。如果是小組件還好,但如果是大組件,那就糟糕了,所以需要避免這種無所謂的更新:
class A extends React.Component { shouldComponentUpdate(nextProps, nextState) { return nextProps.name === this.props.name ? true : false } render() { console.log("A::render") return "A" } } class B extends React.Component { shouldComponentUpdate(nextProps, nextState) { return nextProps.name === this.props.name ? false : true } render() { console.log("B::render") return "A" } }
我在促發這個方法的時候,A組件返回 true,B 組件返回false,查看瀏覽器,可以發現,觸發該方法的時候 A渲染了,而B沒有渲染
componentWillUpdate(nextProps, nextState)
沒啥卵用,和componentDidUpdate組成一對兒,如果業務需要,就用
componentDidUpdate()
沒啥卵用,和componentWillUpdate組成一對兒,如果業務需要,就用
componentWillUnmount
用于清理資源或者事件
class Content extends React.Component { constructor() { super() this.state = { num: 1 } setInterval(() => { this.setState({ num: ++this.state.num }) console.log(this.state.num) }, 1000) } render() { return this.state.num } } class App extends React.Component { constructor() { super() this.state = { show: true } setTimeout(() => { this.setState({ show: false }) },2000) } render() { return this.state.show ?: null } } ReactDom .render( , document .getElementById( "app" ) )
我們在App組件中掛載Content組件,而Content組件則使用定時器每秒更新一次,但是在2s 之后,我們在App組件中卸載這個組件,但是,查看瀏覽器可以發現,定時器依舊在工作,并且報錯:
如果我們返回顯示隱藏組件,就會積累越來越多的定時器。然后就爆炸了。 ``` class Content extends React.Component { constructor() { super() this.state = { num: 1 } this.interval=setInterval(() => { this.setState({ num: ++this.state.num }) console.log(this.state.num) }, 1000) } render() { return this.state.num } componentWillUnmount(){ clearInterval(this.interval) } } ``` 這么解決0x006 總結
在不同的生命周期做不同的事。
0x007 資源:react
源碼
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/97082.html
摘要:概述上一章只是稍微了解了一下和相關的簡單用法,這一章需要講一下組件的生命周期。生命周期的概念這玩意似乎很高大上,其實就是一個假概念罷了,直接來實現一個類似的吧。 0x000 概述 上一章只是稍微了解了一下state和setState相關的簡單用法,這一章需要講一下組件的生命周期。 0x001 生命周期的概念 這玩意似乎很高大上,其實就是一個假概念罷了,直接來實現一個類似的吧。大凡事物從...
摘要:的全稱是統一資源定位符英文,可以這么說,是一種標準,而網址則是符合標準的一種實現而已。渲染器,將組件渲染到頁面上。 0x000 概述 從這一章開始就進入路由章節了,并不直接從如何使用react-route來講,而是從路由的概念和實現來講,達到知道路由的本質,而不是只知道如何使用react-route庫的目的,畢竟react-route只是一個庫,是路由的一個實現而已,而不是路由本身。 ...
摘要:考慮到是快速入門,于是乎我們就記住一點,當修改值需要重新渲染的時候,的機制是不會讓他全部重新渲染的,它只會把你修改值所在的重新更新。這一生命周期返回的任何值將會作為參數被傳遞給。 安裝react npm install creat-react-app -gshowImg(https://segmentfault.com/img/remote/1460000015639868); 這里直...
摘要:生命周期在版本中引入了機制。以后生命周期圖解不包含官方不建議使用的事件處理事件的命名采用小駝峰式,而不是純小寫。只是在兄弟節點之間必須唯一受控組件使的成為唯一數據源。 react 基礎 JSX JSX是一個 JavaScript 的語法擴展,可以很好地描述 UI 應該呈現出它應有交互的本質形式。 React DOM 在渲染所有輸入內容之前,默認會進行轉義。它可以確保在你的應用中,永遠...
摘要:概述不到必要不要在中訪問,嘗試使用的思想去解決問題。當然,必要的時候還是可以的,比如某些依賴的組件時機在中,并不是任何時候都可以訪問的,需要講究時機。 0x000 概述 不到必要不要在React中訪問Dom,嘗試使用React的思想去解決問題。當然,必要的時候還是可以的,比如某些依賴Dom的組件 0x001 時機 在React中,并不是任何時候都可以訪問Dom的,需要講究時機。因為Re...
閱讀 1080·2021-11-25 09:43
閱讀 703·2021-11-22 14:45
閱讀 3830·2021-09-30 09:48
閱讀 1069·2021-08-31 09:41
閱讀 1977·2019-08-30 13:52
閱讀 1983·2019-08-30 11:24
閱讀 1351·2019-08-30 11:07
閱讀 958·2019-08-29 12:15