電子商務(wù)網(wǎng)站的作用有哪些泰安網(wǎng)站優(yōu)化公司
文章目錄
- 2.6. 組件的生命周期
- 2.6.1. 效果
- 2.6.2. 理解
- 2.6.3. 生命周期流程圖(舊)
- 2.6.4. 生命周期流程圖(新)
- 2.6.5. ==重要的勾子==
- 2.6.6. 即將廢棄的勾子
- 2.6.7 getSnapshotBeforeUpdate
- 2.7. 虛擬DOM與DOM Diffing算法
- 2.7.1. 效果
- 2.7.2. 基本原理圖
2.6. 組件的生命周期
2.6.1. 效果
需求:定義組件實(shí)現(xiàn)以下功能:
- 讓指定的文本做顯示 / 隱藏的漸變動(dòng)畫(huà)
- 從完全可見(jiàn),到徹底消失,耗時(shí)2S
- 點(diǎn)擊“不活了”按鈕從界面中卸載組件
<!-- 準(zhǔn)備好一個(gè)“容器” -->
<div id="test"></div>
<!-- 引入三個(gè)庫(kù) -->
<script type="text/babel">class Demo extends React.Component{state = {opacity:1}death = ()=>{//卸載組件ReactDOM.unmountComponentAtNode(document.getElementById('test'))}//組件掛完畢componentDidMount(){console.log('componentDidMount');this.timer = setInterval(() => {//獲取原狀態(tài)let {opacity} = this.state//減小0.1opacity -= 0.1if(opacity <= 0) opacity = 1//設(shè)置新的透明度this.setState({opacity})}, 200);}//組件將要卸載componentWillUnmount(){//清除定時(shí)器clearInterval(this.timer)}//初始化渲染、狀態(tài)更新之后render(){console.log('render');return(<div><h2 style={{opacity:this.state.opacity}}>React學(xué)不會(huì)怎么辦?</h2><button onClick={this.death}>不活了</button></div>)}}//渲染組件到頁(yè)面ReactDOM.render(<Demo a="1" b="2"/>,document.getElementById('test'))
</script>
2.6.2. 理解
1.組件從創(chuàng)建到死亡它會(huì)經(jīng)歷一些特定的階段。
2.React組件中包含一系列勾子函數(shù)(生命周期回調(diào)函數(shù)), 會(huì)在特定的時(shí)刻調(diào)用。
3.我們?cè)诙x組件時(shí),會(huì)在特定的生命周期回調(diào)函數(shù)中,做特定的工作。
2.6.3. 生命周期流程圖(舊)
生命周期的三個(gè)階段(舊)
- 初始化階段: 由ReactDOM.render()觸發(fā)—初次渲染
1.constructor()
2.componentWillMount()
3.render()
4.componentDidMount() - 更新階段: 由組件內(nèi)部this.setSate()或父組件重新render觸發(fā)
1.shouldComponentUpdate()=
2.componentWillUpdate()
3.render()
4.componentDidUpdate() - 卸載組件: 由ReactDOM.unmountComponentAtNode()觸發(fā)
1.componentWillUnmount()
<!-- 準(zhǔn)備好一個(gè)“容器” -->
<div id="test"></div>
<!-- 引入三個(gè)庫(kù) -->
<script type="text/babel">/* 1. 初始化階段: 由ReactDOM.render()觸發(fā)---初次渲染1. constructor()2. componentWillMount()3. render()4. componentDidMount() =====> 常用一般在這個(gè)鉤子中做一些初始化的事,例如:開(kāi)啟定時(shí)器、發(fā)送網(wǎng)絡(luò)請(qǐng)求、訂閱消息2. 更新階段: 由組件內(nèi)部this.setSate()或父組件render觸發(fā)1. shouldComponentUpdate()2. componentWillUpdate()3. render() =====> 必須使用的一個(gè)4. componentDidUpdate()3. 卸載組件: 由ReactDOM.unmountComponentAtNode()觸發(fā)1. componentWillUnmount() =====> 常用一般在這個(gè)鉤子中做一些收尾的事,例如:關(guān)閉定時(shí)器、取消訂閱消息*/class Demo extends React.Component{constructor(props){console.log("Count---construtor");super(props)//初始化狀態(tài)this.state = {count:0}}//加按鈕的回調(diào)add = () =>{//獲取原狀態(tài)const {count} = this.state;this.setState({count:count+1})}//卸載組件按鈕的回調(diào)dath = ()=>{React.unmountComponentAtNode(document.getElementById('test'))}//強(qiáng)制更新的按鈕force = ()=>{this.forceUpdate()}//組件將要掛在的鉤子函數(shù)componentWillMount(){console.log('Count---componentWillMount');}//組件掛在完畢componentDidMount(){console.log('Count---componentDidMount');}//組件將要卸載的鉤子componentWillUnmount(){console.log('Count---componentWillUnmount');}//控制組件更新的閥門,默認(rèn)為true,必須要有返回值shouldComponentUpdate(){console.log('Count---shouldComponentUpdate');return true}//組件將要更新的鉤子componentWillUpdate(){console.log('Count---componentWillUpdate');}//組件更新完畢的鉤子componentDidUpdate(){console.log('Count---componentDidUpdate');}render(){console.log('Count---render');const {count} = this.statereturn(<div><h2>當(dāng)前求和為:{count}</h2><button onClick={this.add}>點(diǎn)我+1</button><button onClick={this.death}>卸載組件</button><button onClick={this.force}>不更改任何狀態(tài)中的數(shù)據(jù),強(qiáng)制更新一下</button></div>)} }//父組件Aclass A extends React.Component{//初始化狀態(tài)state = {carName:'奔馳'}changeCar = ()=>{this.setState({carName:'奧拓'})}render(){return(<div><div>我是A組件</div><button onClick={this.changeCar}>換車</button><B carName={this.state.carName}/></div>)}}//子組件Bclass B extends React.Component{//組件將要接收新的props的鉤子componentWillReceiveProps(props){console.log('B---componentWillReceiveProps',props);}//控制組件更新的“閥門”shouldComponentUpdate(){console.log('B---shouldComponentUpdate');return true}//組件將要更新的鉤子componentWillUpdate(){console.log('B---componentWillUpdate');}//組件更新完畢的鉤子componentDidUpdate(){console.log('B---componentDidUpdate');}render(){console.log('B---render');return(<div>我是B組件,接收到的車是:{this.props.carName}</div>)}}//渲染組件到頁(yè)面ReactDOM.render(<Demo a="1" b="2"/>,document.getElementById('test'))
</script>
2.6.4. 生命周期流程圖(新)
生命周期的三個(gè)階段(新)
- 初始化階段: 由ReactDOM.render()觸發(fā)—初次渲染
1.constructor()
2.getDerivedStateFromProps
3.render()
4.componentDidMount() - 更新階段: 由組件內(nèi)部this.setSate()或父組件重新render觸發(fā)
1.getDerivedStateFromProps
2.shouldComponentUpdate()
3.render()
4.getSnapshotBeforeUpdate
5.componentDidUpdate() - 卸載組件: 由ReactDOM.unmountComponentAtNode()觸發(fā)
1.componentWillUnmount()
<!-- 準(zhǔn)備好一個(gè)“容器” -->
<div id="test"></div>
<!-- 引入三個(gè)庫(kù) -->
<script type="text/babel">/* 1. 初始化階段: 由ReactDOM.render()觸發(fā)---初次渲染1. constructor()2. getDerivedStateFromProps 3. render()4. componentDidMount() =====> 常用一般在這個(gè)鉤子中做一些初始化的事,例如:開(kāi)啟定時(shí)器、發(fā)送網(wǎng)絡(luò)請(qǐng)求、訂閱消息2. 更新階段: 由組件內(nèi)部this.setSate()或父組件重新render觸發(fā)1. getDerivedStateFromProps2. shouldComponentUpdate()3. render()4. getSnapshotBeforeUpdate5. componentDidUpdate()3. 卸載組件: 由ReactDOM.unmountComponentAtNode()觸發(fā)1. componentWillUnmount() =====> 常用一般在這個(gè)鉤子中做一些收尾的事,例如:關(guān)閉定時(shí)器、取消訂閱消息*/class Demo extends React.Component{//構(gòu)造器constructor(props){console.log('Count---constructor');super(props)//初始化狀態(tài)this.state = {count:0}}//加1按鈕的回調(diào)add = ()=>{//獲取原狀態(tài)const {count} = this.state//更新?tīng)顟B(tài)this.setState({count:count+1})}//卸載組件按鈕的回調(diào)death = ()=>{ReactDOM.unmountComponentAtNode(document.getElementById('test'))}//強(qiáng)制更新按鈕的回調(diào)force = ()=>{this.forceUpdate()}//若state的值在任何時(shí)候都取決于props,那么可以使用getDerivedStateFromPropsstatic getDerivedStateFromProps(props,state){console.log('getDerivedStateFromProps',props,state);return null}//在更新之前獲取快照getSnapshotBeforeUpdate(){console.log('getSnapshotBeforeUpdate');return 'atguigu'}//組件掛載完畢的鉤子componentDidMount(){console.log('Count---componentDidMount');}//組件將要卸載的鉤子componentWillUnmount(){console.log('Count---componentWillUnmount');}//控制組件更新的“閥門”shouldComponentUpdate(){console.log('Count---shouldComponentUpdate');return true}//組件更新完畢的鉤子componentDidUpdate(preProps,preState,snapshotValue){console.log('Count---componentDidUpdate', preProps, preState, snapshotValue);}render(){console.log('Count---render');const {count} = this.statereturn(<div><h2>當(dāng)前求和為:{count}</h2><button onClick={this.add}>點(diǎn)我+1</button><button onClick={this.death}>卸載組件</button><button onClick={this.force}>不更改任何狀態(tài)中的數(shù)據(jù),強(qiáng)制更新一下</button></div>)}}//渲染組件到頁(yè)面ReactDOM.render(<Demo a="1" b="2"/>,document.getElementById('test'))
</script>
2.6.5. 重要的勾子
1.render:初始化渲染或更新渲染調(diào)用
2.componentDidMount:開(kāi)啟監(jiān)聽(tīng), 發(fā)送ajax請(qǐng)求
3.componentWillUnmount:做一些收尾工作, 如: 清理定時(shí)器
2.6.6. 即將廢棄的勾子
1.componentWillMount
2.componentWillReceiveProps
3.componentWillUpdate
現(xiàn)在使用會(huì)出現(xiàn)警告,下一個(gè)大版本需要加上UNSAFE_前綴才能使用,以后可能會(huì)被徹底廢棄,不建議使用。
2.6.7 getSnapshotBeforeUpdate
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>4_getSnapShotBeforeUpdate的使用場(chǎng)景</title><style>.list{width: 200px;height: 150px;background-color: skyblue;overflow: auto;}.news{height: 30px;}</style>
</head>
<body><!-- 準(zhǔn)備好一個(gè)“容器” --><div id="test"></div><!-- 引入react核心庫(kù) --><script type="text/javascript" src="../js/17.0.1/react.development.js"></script><!-- 引入react-dom,用于支持react操作DOM --><script type="text/javascript" src="../js/17.0.1/react-dom.development.js"></script><!-- 引入babel,用于將jsx轉(zhuǎn)為js --><script type="text/javascript" src="../js/17.0.1/babel.min.js"></script><script type="text/babel">class NewsList extends React.Component{state = {newsArr:[]}componentDidMount(){setInterval(() => {//獲取原狀態(tài)const {newsArr} = this.state//模擬一條新聞const news = '新聞'+ (newsArr.length+1)//更新?tīng)顟B(tài)this.setState({newsArr:[news,...newsArr]})}, 1000);}getSnapshotBeforeUpdate(){return this.refs.list.scrollHeight}componentDidUpdate(preProps,preState,height){this.refs.list.scrollTop += this.refs.list.scrollHeight - height}render(){return(<div className="list" ref="list">{this.state.newsArr.map((n,index)=>{return <div key={index} className="news">{n}</div>})}</div>)}}ReactDOM.render(<NewsList/>,document.getElementById('test'))</script>
</body>
</html>
2.7. 虛擬DOM與DOM Diffing算法
2.7.1. 效果
需求:驗(yàn)證虛擬DOM Diffing算法的存在
2.7.2. 基本原理圖
經(jīng)典面試題:1). react/vue中的key有什么作用?(key的內(nèi)部原理是什么?)2). 為什么遍歷列表時(shí),key最好不要用index?1. 虛擬DOM中key的作用:1) key是虛擬DOM對(duì)象的標(biāo)識(shí), 在更新顯示時(shí)key起著極其重要的作用。2). 詳細(xì)的說(shuō): 當(dāng)狀態(tài)中的數(shù)據(jù)發(fā)生變化時(shí),react會(huì)根據(jù)【新數(shù)據(jù)】生成【新的虛擬DOM】, 隨后React進(jìn)行【新虛擬DOM】與【舊虛擬DOM】的diff比較,比較規(guī)則如下:a. 舊虛擬DOM中找到了與新虛擬DOM相同的key:(1).若虛擬DOM中內(nèi)容沒(méi)變, 直接使用之前的真實(shí)DOM(2).若虛擬DOM中內(nèi)容變了, 則生成新的真實(shí)DOM,隨后替換掉頁(yè)面中之前的真實(shí)DOMb. 舊虛擬DOM中未找到與新虛擬DOM相同的key根據(jù)數(shù)據(jù)創(chuàng)建新的真實(shí)DOM,隨后渲染到到頁(yè)面2. 用index作為key可能會(huì)引發(fā)的問(wèn)題:1. 若對(duì)數(shù)據(jù)進(jìn)行:逆序添加、逆序刪除等破壞順序操作:會(huì)產(chǎn)生沒(méi)有必要的真實(shí)DOM更新 ==> 界面效果沒(méi)問(wèn)題, 但效率低。2. 如果結(jié)構(gòu)中還包含輸入類的DOM:會(huì)產(chǎn)生錯(cuò)誤DOM更新 ==> 界面有問(wèn)題。3. 注意!如果不存在對(duì)數(shù)據(jù)的逆序添加、逆序刪除等破壞順序操作,僅用于渲染列表用于展示,使用index作為key是沒(méi)有問(wèn)題的。3. 開(kāi)發(fā)中如何選擇key?1.數(shù)據(jù)的唯一標(biāo)識(shí)作為key, 比如id、手機(jī)號(hào)、身份證號(hào)、學(xué)號(hào)等唯一值。2.如果確定只是簡(jiǎn)單的展示數(shù)據(jù),用index也是可以的。