react使用节流防抖性能优化-获取自定义属性-函数传参-基础语法

/*
 * @Description: react基础语法集锦,每天了解一点点
 * @Version: 2.0
 * @Autor: lhl
 * @Date: 2020-06-01 10:20:33
 * @LastEditors: lhl
 * @LastEditTime: 2020-06-01 11:47:26
*/ 

// props和state的不同?props 是传递给组件的(类似于函数的形参),而 state 是在组件内被组件自己管理的(类似于在一个函数内声明的变量)

import React, { Component } from 'react'
import _ from 'lodash';

export default class App extends Component {
  render() {
    return (
      <div>
        <p>hello react</p>
        <Foo></Foo>
        <Bar></Bar>
        <LoadMore></LoadMore>
        <Searchbox></Searchbox>
      </div>
    )
  }
}

class Foo extends Component {
  // 点击事件
  // 在 render 方法中使用 Function.prototype.bind 会在每次组件渲染时创建一个新的函数,可能会影响性能
  // 在 render 方法中使用箭头函数也会在每次组件渲染时创建一个新的函数,这会破坏基于恒等比较的性能优化。
  // 函数传递参数的方式一
  handleClick(id) {
    console.log('Click callback render箭头函数',id,this); // 输出 Click callback render箭头函数 1 和 组件实例
  }
  render() {
    return (
      <div>
        <button onClick={() => this.handleClick(1)}>Click Foo</button>
      </div>
    )
  }
}

class Bar extends Component {
  // 点击事件
  // 为什么我的函数每次组件渲染时都会被调用? 正确做法是,传递函数本身(不带括号)
  // 函数传递参数的方式二
  handleClick(name){
    console.log('Click callback',name,this); // 输出 Click callback 'bob' 和 组件实例
  }
  // react 通过 data-attributes 传递参数
  handleClickGetAttributes = (e) =>{
    console.log(e.target.dataset.id,e.target.dataset.url) // 1 https//www.baidu.com
  }
  render() {
    return (
      <div>
        <p data->this.handleClickGetAttributes}>react获取自定义属性</p>
        <button onClick={this.handleClick.bind(this,'bob')}>Click Bar</button>
      </div>
    )
  }
}

// 怎样阻止函数被调用太快或者太多次? 节流 防抖 lodash库提供了节流和防抖的函数 npm i lodash -S 安装
class LoadMore extends React.Component {
  constructor(props) {
    super(props);
    this.handleClick = this.handleClick.bind(this);
    this.handleClickThrottled = _.throttle(this.handleClick, 1000);
  }
  // _.debounce、_.throttle 和 raf-schd 都提供了一个 cancel 方法来取消延迟回调。你需要在 componentWillUnmount 中调用该方法,或者对代码进行检查来保证在延迟函数有效期间内组件始终挂载
  componentWillUnmount() {
    this.handleClickThrottled.cancel();
  }
  render() {
    return <button onClick={this.handleClickThrottled}>Load More</button>;
  }
  handleClick() {
    console.log(111) // 使其每秒钟的只能调用一次
  }
}

// 防抖确保函数不会在上一次被调用之后一定量的时间内被执行。当必须进行一些费时的计算来响应快速派发的事件时(比如鼠标滚动或键盘事件时),防抖是非常有用的
class Searchbox extends React.Component {
  constructor(props) {
    super(props);
    this.handleChange = this.handleChange.bind(this);
    this.emitDebounced = _.debounce(this.emitChange, 1000);
  }

  componentWillUnmount() {
    this.emitDebounced.cancel();
  }

  render() {
    return (
      <input
        type="text"
        onChange={this.handleChange}
        placeholder="Search..."
        defaultValue={this.props.value}
      />
    );
  }

  handleChange(e) {
    this.emitDebounced(e.target.value);
  }

  emitChange(value) {
    console.log(value,'value') // 1s 的延迟来改变文本输入
  }
}