react事件、ref应用、状态、列表渲染

374 阅读3分钟

我正在参加「掘金·启航计划」

一、事件绑定

1.1、react事件绑定和原生js事件绑定

react事件绑定和原生js事件绑定有什么区别? react事件绑定没用具体的绑定在dom节点上,采用的是一种事件代理的模式。好处占有内存非常小。

和普通浏览器一样,事件 handler会被自动传入一个event对象,这个对象和普通的浏览器event对象所包含的方法和属性都基本一致,不同的是React中的event对象并不是浏览器提供的,而是它自己内部所构建的,它同样具有event.stopPropagationevent.preventDefault这种常用的方法。


1.2、事件绑定4种方式及this指向

新建event.js,写入:

import React, { Component } from 'react'

export default class Event extends Component {
  a = 100
  render() {
    return (
      <div>
          <div>
            <input />
            <button onClick={() => {
                console.log('add1', this.a) // this 指向Event类
            }}>add1</button>
            <button onClick={this.handleClick2.bind(this)}>add2</button> {/* 使用bind改变this指向,并且不自动执行,call和apply会自动执行,bind不会自动执行 */}
            <button onClick={this.handleClick3}>add3</button> {/* 推荐这种写法 */}
            <button onClick={() => this.handleClick4()}>add4</button> {/* 推荐这种写法+1 */}
          </div>
      </div>
    )
  }

  handleClick2() {
    // console.log('add2', this.a)// 报错
    console.log('add2', this.a, this)// this undefined  this指向问题指向undefined 使用bind改变this指向
  }

  handleClick3 = (event) => {
      console.log('add3', this.a, event)
  }

  handleClick4 = () => {
    console.log('add4', this.a)
  }
}

/*
 tip:延伸
 js中改变this指向3中方法
 call: 改变this指向,并且自动执行函数
 apply: 改变this指向,并且自动执行函数
 bind: 改变this指向,需要加小括号手动执行函数
*/
var obj1 = {
    name: 'obj1',
    getName() {
        console.log(this.name)
    }
}

var obj2 = {
    name: 'obj2',
    getName() {
        console.log(this.name)
    }
}
obj1.getName.call(obj2);
obj2.getName.apply(obj1);
obj2.getName.bind(obj1)();

效果: 在这里插入图片描述


二、ref应用

新建ref.js写入:

import React, { Component } from 'react'

export default class Ref extends Component {
 
  myref = React.createRef()

  render() {
    return (
      <div>
          <div>
            {/* <input ref="name"/>
            <button onClick={() => {
                console.log('add1', this.refs.name.value) // this.refs将被弃用
            }}>add</button> */}
            <input ref={this.myref}/>
            <button onClick={() => {
                console.log('add1', this.myref.current.value)
            }}>add</button>
          </div>
      </div>
    )
  }
}

index.js修改引用: 在这里插入图片描述 效果: 在这里插入图片描述


三、状态(state)

状态就是组件描述某种显示情况的数据,由组件自己设置和更改,也就是说由组件自己维护,使用状态的目的就是为了在不同的状态下使组件的显示不同(自己管理,在react中尽量减少对dom的操作。声明式设计。) 新建state.js写入:

import React, { Component } from 'react'

export default class State extends Component {
  state = {
    flag: true
  }
  render() {
    return (
      <div>
          <h1>react状态</h1>
          <button onClick={() => {
              this.setState({
                  flag: !this.state.flag
              })
          }}>{this.state.flag ? '收藏' : '取消收藏'}</button>
      </div>
    )
  }
}

index.js修改: 在这里插入图片描述

效果: 在这里插入图片描述 在这里插入图片描述 state.js状态写法也可写成如下:

import React, { Component } from 'react'

export default class State extends Component {
  constructor() {
      super()
      this.state = {
          flag: true
      }
  }
  render() {
    return (
      <div>
          <h1>react状态</h1>
          <button onClick={() => {
              this.setState({
                  flag: !this.state.flag
              })
          }}>{this.state.flag ? '收藏' : '取消收藏'}</button>
      </div>
    )
  }
}

四、列表渲染

React的高效依赖于所谓的Virtual-DOM,尽量不碰DOM。对于列表元素来说会有一个问题:元素可能会在一个列表中改变位置。要实现这个操作,只需要交换一下DOM位置就好了,但是React并不知道其实我们只是改变了元素的位置,所以它会重新渲染后面两个元素(再执行Virtual-DOM),这样会大大增加DOM操作。但如果给每个元素加上唯一的标识,React就可以知道这两个元素只是交换了位置,这个标识就是key,这个key必须是每个元素的唯一标识,不能重复。

创建arr.js写入:

import React, { Component } from 'react'

export default class Arr extends Component {
    state = {
        arr: [0, 1, 2, 3, 4, 5]
    }
  render() {
    // 设置key值:为了列表的复用和重排,设置key值,提高性能
    var newArr = this.state.arr.map((item, index) => <li key={index}>{item}</li>)

    return (
      <div>
          <ul>
              {newArr}
          </ul>
      </div>
    )
  }
}

index.js中引入: 在这里插入图片描述 效果: 在这里插入图片描述

在学习React的路上,如果你觉得本文对你有所帮助的话,那就请关注点赞评论三连吧,谢谢,你的肯定是我写博的另一个支持。