React 周期函数与双向数据绑定冲突

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对性能的追求
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值