setState的使用+React更新机制+events+受控和非受控组件

setState是异步更新
总结:
1.setState设计为异步,可以显著的提升性能

  • 如果每次调用 setState都进行一次更新,那么意味着render函数会被频繁调用,界面重新染,这样效率是很低的;
  • 最好的办法应该是获取到多个更新,之后进行批量更新;
    2.如果同步更新了state,但是还没有执行render函数,那么state和props不能保持同步;
  • state和props不能保持一致性,会在开发中产生很多的问题;

如何获取state的结果

import React, { Component } from 'react'

export default class anli extends Component {
  constructor(props){
    super(props);
    this.state={
      counter:0,
      message:'hi'
    }

  }
  render() {
    return (
      <div>
        <button onClick={e=>this.increment()}>改字段</button>
        <h2>{this.state.message}</h2>
      </div>
    )
  }
  componentDidUpdate(){
    // 方式二:获取异步更新的state
    console.log(this.state.message)
  }

  increment(){
    //方式一:获取异步更新后的数据
    // setState(更新的state,回调函数)
    this.setState({
      message:'hello'
    },()=>{
      console.log('message',this.state.message)
    })

  }
}

同步更新setState
说明一下,我测试的并不是这样,还是异步。我目前还未找到原因
在这里插入图片描述
setState合并时进行累加

this.setState((prevState,props)=>{
	return {
		counter:preState.counter+1
	}
})

React更新机制

在这里插入图片描述
React在props或state发生改变时,会调用React的render方法,会创建一颗不同的树

react性能优化

  • 列表中keys的作用
  • 组件嵌套的render调用

key的注意事项

  • key应该是唯一的
  • key不要使用随机数(随机数在下一次render时,会重新生成一个数字)
  • 使用index作为key,对性能是没有优化的

shouldComponentUpdate 用法

  shouldComponentUpdate(nextProps,nextState){
    // 返回true,调用render方法。返回false,不调用remder方法
    if(this.state.counter !== nextState.counter){
      return true
    }
    return false;
  }

render 只想改变一次 ,继承pureComponent(不能解决函数式再次渲染)

函数组件使用memo

import React, { Component, PureComponent,memo } from 'react'
// Header
const MemoHeader = memo(
  function Header(){
    console.log('Header 被调用了')
    return <h2>我是header组件</h2>
  }
)

// Main
class Main extends Component{
  render(){
    console.log('main 被调用')
    return <h3>我是main组件</h3>
  }
}

// banner
class Banner extends PureComponent{
  render(){
    console.log('banner 被调用')
    return <h3>我是banner组件</h3>
  }
}

export default class anli extends PureComponent {
  constructor(props){
    super(props);
    this.state={
      counter:0,
      message:'hi'
    }

  }
  render() {
    console.log('APP render函数被调用')
    return (
      <div>
        <MemoHeader></MemoHeader>
        <Banner></Banner>
        <Main></Main>
        <h2>当前计数:{this.state.counter}</h2>
        <button onClick={e=>this.changeText()}>改文本</button>
        <button onClick={e=>this.increment()}>改文本</button>        
      </div>
    )
  }


  changeText(){
    this.setState({
      message:'hello0'
    });
  }

  increment(){
    this.setState({
      counter:this.state.counter+1
    })
  }
}


问题:

  • 全局事件传递events
  • setState传递的数据需要是不可变的数据

setState不可变

insertData(){
	const newFriends = [...this.state.friends];
	newFriends.push[{name:'tom',age:20}]
	this.setState({
		friends:newFriends
	})
	
}

全局事件传递

安装events

yarn add events
import React, { PureComponent } from 'react'
import {EventEmitter} from 'events'
// 事件总线:event bus
const eventBus = new EventEmitter();

class Home extends PureComponent{
  // 添加事件监听
  componentDidMount(){
    eventBus.addListener('sayHello',this.handleSayHelloListener)
  }

  // 取消事件监听
  componentWillUnmount(){
    // 取消所有的sayhello事件
    eventBus.removeListener('sayHello',this.handleSayHelloListener)
  }

  handleSayHelloListener(num,message){
    console.log(num,message)
  }
  render(){
    return (
      <div>
        Home
      </div>
    )
  }
}

class Profile extends PureComponent{
  render() {
    return (
      <div>
        Profile
        <button onClick={e=>this.emmitEvent()}>点击Profile</button>
      </div>
    )
  }

  emmitEvent(){
    eventBus.emit('sayHello','hello home',123)
  }
}

export default class anli extends PureComponent {
  render() {
    return (
      <div>
        <Home />
        <Profile />
      </div>
    )
  }
}

受控和非受控组件

1.如何使用ref

创建refs来获取对应的DOM。

import React, { PureComponent,createRef } from 'react'

export default class anli extends PureComponent {

  constructor(props){
    super(props);
    
    this.titleRef = createRef();
    this.titleEl = null
  }

  render() {
    return (
      <div>
        {/* ref=字符串/对象/函数 */}
        <h2 ref='titleRef'>hello</h2>
        {/* 目前react推荐的方式 */}
        <h2 ref={this.titleRef}>react</h2>

        <h2 ref={(arg)=>{this.titleEl=arg}}>hello</h2>
        <button onClick={e=>this.changeText()}>改变文本</button>
      </div>
    )
  }

  changeText(){
    // 1. 使用方式一:字符串(不推荐)
   this.refs.titleRef.innerHTML = 'react'
   // 2.使用方式二:对象方式
   this.titleRef.current.innerHTML = 'hello javascript'
   //3.回调函数方式
    this.titleEl.innerHTML='functiona'
  }
}

受控组件
我的理解就是 表单,双向绑定

import React, { PureComponent } from 'react'

export default class anli extends PureComponent {
  constructor(props){
    super(props);
    this.state = {
      username:'',
      password:'',
      vaild:''
    }
  }

  render() {
    return (
      <div>
        <form onSubmit={e=>this.handleSubmit(e)}>
          <label htmlFor="username">
            用户:
            <input type="text" 
                   id='username'  
                   name='username'
                   value={this.state.username}
                  onChange={e=>this.handleChange(e)}/>
          </label>
          <label htmlFor="password">
            密码:
            <input type="text" 
                   id='password'  
                   name='password'
                   value={this.state.password}
                  onChange={e=>this.handleChange(e)}/>
          </label>
          <label htmlFor="vaild">
            验证:
            <input type="text"   
                   id='vaild'  
                   name='vaild'
                   value={this.state.vaild}
                  onChange={e=>this.handleChange(e)}/>
          </label>
          <input type="submit" value='提交' />
        </form>
      </div>
    )
  }
  handleSubmit(event){
    // 取消默认行为
    event.preventDefault();
  }

  handleChange(event){
    this.setState({
      // 计算属性名
      [event.target.name]:event.target.value
    })
  }
}


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值