1.react 的shouldComponentUpdate生命周期函数优化页面性能
2.react的双向数据绑定
3.实现react 周期函数的性能优化与数据绑定共存
1.react 的shouldComponentUpdate生命周期函数优化页面性能
index.js里面一共定义了三个组件
import React, { Component } from 'react'
import ReactDOM from 'react-dom'
class Mouse extends Component{
state = {
x:0,
y:0
}
//监听鼠标移动事件
componentDidMount(){
window.addEventListener('mousemove',this.handleMouseMove)
}
handleMouseMove= (e)=>{
this.setState({
x:e.clientX,
y:e.clientY
})
}
render(){
// 向外界提供当前子组件的数据
// return this.props.render(this.state)
return(
<div>
x:{this.state.x},y:{this.state.y}
</div>
)
}
}
class ChangeNumber extends React.Component{
// class ChangeNumber extends React.PureComponent{
// shouldComponentUpdate(nextProps,nextState){
// return this.props.number !== nextProps.number
// }
// 没有周期函数,是可以正常使用的,但是同时存在就会失效
// constructor(props){
// super()
// this.state={
// value:props.value,
// number:props.number
// }
// }
render(){
// 此时即可以实现数据不同的时候才会更新组件,还会实现数据双向数据绑定
console.log(this.props)
return (
<div>
<button onClick={this.props.change}>生成随机数</button>
<br />
{/* <input type = "text" value = {this.state.value} onChange={this.Input}/> */}
</div>
)
}
Input = (e)=>{
console.log(e.target.value)
this.setState({
value:e.target.value
})
}
}
class App extends Component {
state = {
number:0,
value:1
}
render() {
return (
<div>
<Mouse></Mouse>
随机数 {this.state.number}
<ChangeNumber {...this.state} change={this.change}></ChangeNumber>
</div>
)
}
change = ()=>{
this.setState({
number:Math.floor(Math.random()*3)
})
}
}
ReactDOM.render(
<App></App>,
document.getElementById('root')
)
上图中Mouse组件与该主题无关,主要监听的是页面中鼠标的移动事件。
App作为页面的主入口,定义了Mouse组件、ChangeNumber组件
App组件将自身的number、Change方法传递到ChangeNumber 组件,
由ChangeNumber组件来渲染内容,并由Change方法改变number的值。
在ChangeNumber组件的render函数打印父组件App传递来的内容
初始页面渲染如图:
点击按钮,生成0-3的随机数,故而有根大的几率会生成同一个随机数,此时更新组件会大大降低页面的性能
由图可见,当随机数生成时,生成同样的数据也会促使ChangeNumber组件更新,这与react追求性能的初衷相悖。故而利用react的shouldComponentUpdate生命周期函数来控制组件是否更新,当return true的时候,会促使ChangeNumber组件更新,反之则不会更新:
将代码改为下图所示:
class ChangeNumber extends React.Component{
// class ChangeNumber extends React.PureComponent{
shouldComponentUpdate(nextProps,nextState){
return this.props.number !== nextProps.number
}
// 没有周期函数,是可以正常使用的,但是同时存在就会失效
// constructor(props){
// super()
// this.state={
// value:props.value,
// number:props.number
// }
// }
render(){
// 此时即可以实现数据不同的时候才会更新组件,还会实现数据双向数据绑定
// console.log(this.props)
console.log('组件更新--->',1)
return (
<div>
<button onClick={this.props.change}>生成随机数</button>
<br />
{/* <input type = "text" value = {this.state.value} onChange={this.Input}/> */}
</div>
)
}
Input = (e)=>{
// console.log(e.target.value)
this.setState({
value:e.target.value
})
}
}
class App extends Component {
state = {
number:0,
value:1
}
render() {
console.log('随机数--->',this.state.number)
return (
<div>
<Mouse></Mouse>
随机数 {this.state.number}
<ChangeNumber {...this.state} change={this.change}></ChangeNumber>
</div>
)
}
change = ()=>{
this.setState({
number:Math.floor(Math.random()*3)
})
}
}
这个时候,只有在生成的随机数不同的时候,才会触发页面的更新,才会打印1:
可以看得出,第二次和第三次生成的随机数均为1,但是组件只更新了1次,此时利用react的shouldComponentUpdate周期函数对页面性能进行了优化。
2.利用react实现双向数据绑定:
跟vue不同,vue中使用v-model可以实现双向数据绑定,但是react双向数据绑定需要自己实现view变化->module变化
由于shouldComponentUpdate与数据双向绑定会冲突,所以这里把shouldComponentUpdate先注释掉:
class ChangeNumber extends React.Component{
// class ChangeNumber extends React.PureComponent{
// shouldComponentUpdate(nextProps,nextState){
// return this.props.number !== nextProps.number
// }
// 没有周期函数,是可以正常使用的,但是同时存在就会失效
constructor(props){
super()
this.state={
value:props.value,
number:props.number
}
}
render(){
// 此时即可以实现数据不同的时候才会更新组件,还会实现数据双向数据绑定
// console.log(this.props)
// console.log('组件更新--->',1)
return (
<div>
<button onClick={this.props.change}>生成随机数</button>
<br />
<input type = "text" value = {this.state.value} onChange={this.Input}/>
</div>
)
}
Input = (e)=>{
console.log(e.target.value)
this.setState({
value:e.target.value
})
}
}
class App extends Component {
state = {
number:0,
value:1
}
此时已经可以实现数据的双向绑定:
3.react的shouldComponentUpdate周期函数与双向数据绑定并存
此时将1中注释掉的shoudComponentUpdate放出来:
class ChangeNumber extends React.Component{
// class ChangeNumber extends React.PureComponent{
shouldComponentUpdate(nextProps,nextState){
return this.props.number !== nextProps.number
}
// 没有周期函数,是可以正常使用的,但是同时存在就会失效
constructor(props){
super()
this.state={
value:props.value,
number:props.number
}
}
render(){
// 此时即可以实现数据不同的时候才会更新组件,还会实现数据双向数据绑定
// console.log(this.props)
// console.log('组件更新--->',1)
console.log('state.value--->',this.state.value)
return (
<div>
<button onClick={this.props.change}>生成随机数</button>
<br />
<input type = "text" value = {this.state.value} onChange={this.Input}/>
</div>
)
}
Input = (e)=>{
console.log('输入框--->',e.target.value)
this.setState({
value:e.target.value
})
}
}
此时的输入框失效,无论输入什么都无法实现数据同步:
将App继承的React.Component更改为React.PureComponent(纯组件),
默认在纯组件内部会执行shouldComponentUpdate,对生成随机数进行监听,只有在数据不一致时,才会实现组件更新
class ChangeNumber extends React.PureComponent{
// shouldComponentUpdate(nextProps,nextState){
// return this.props.number !== nextProps.number
// }
// 没有周期函数,是可以正常使用的,但是同时存在就会失效
constructor(props){
super()
this.state={
value:props.value,
number:props.number
}
}
render(){
// 此时即可以实现数据不同的时候才会更新组件,还会实现数据双向数据绑定
// console.log(this.props)
// console.log('组件更新--->',1)
console.log('state.value--->',this.state.value)
return (
<div>
<button onClick={this.props.change}>生成随机数</button>
<br />
<input type = "text" value = {this.state.value} onChange={this.Input}/>
</div>
)
}
Input = (e)=>{
console.log('输入框--->',e.target.value)
this.setState({
value:e.target.value
})
}
}
既可以实现数据双向数据绑定,又可以实现只有当生成的随机数发生变化的时候才会使得Component组件更新,实现了react对性能的追求