前端小白学 React 框架(四)

1,020 阅读4分钟

React事件绑定

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

热身运动 🏃🏻‍♂️

现在有两个问题来回答一下 🧐:

第一个问题是如果原生DOM原生有一个监听事件,我们可以如何操作呢?

  • 方式一: 获取DOM原生,添加监听事件;
  • 方式二: 在HTML原生中,直接绑定onclick;

第二个问题是在React中是如何操作呢?

  • React 事件的命名采用小驼峰式而不是纯小写
  • 我们需要通过{}传入一个事件处理函数,这个函数会在事件发生时被执行

this指向

this的四种绑定规则:

  1. 默认绑定: 独立执行,如foo(),指向window或者undefined
  2. 隐式绑定: 被一个对象执行,如obj.foo()指向obj
  3. 显式绑定: call/apply/bind,那么foo.call("aaa")后指向String("aaa")
  4. new绑定: new Foo(),创建一个新对象,并且赋值给this

Babel中使用的是严格模式

解决事件绑定的this指向问题

为什么直接打印this的时候显示的是undefined呢?原因是onClick函数并不是我们主动调用的,而当button发生改变时,React内部调用了onClick函数而它内部调用时,并不知道要如何绑定正确的this;

那么如何解决this的问题呢?

  • 方案一: bindonClick显示绑定this
  • 方案二: 使用 ES6 class fields 语法
  • 方案三: 事件监听时传入箭头函数 (个人推荐)

bind绑定

这个方法是在官方文档里有写的

class App extends React.Component {
  constructor() {
    // ...
    this.foo = this.foo.bind(this);
  }

  foo() {
    console.log('foo click', this);
  }

  render() {
    // ...
    return (
      <div>
        // ...
        <button onClick={this.foo}>foo点击</button>
      </div>
    )
  }
}

ES6的class field

class App extends React.Component {
  constructor() {
    // ...
  }

  bar = () => {
    console.log('bar click', this);
  }

  render() {
    // ...
    return (
      <div>
        // ...
        <button onClick={this.bar}>bar点击</button>
      </div>
    )
  }
}

直接传入一个箭头函数

这个方法比较常用,而且传入参数非常方便

class App extends React.Component {
  constructor() {
    // ...
  }

  // ...

  render() {
    // ...
    return (
      <div>
        // ...
        <button onClick={() => console.log('箭头函数 click', this)}>箭头函数点击</button>
      </div>
    )
  }
}

参数传递

在执行事件函数时,有可能我们需要获取一些参数信息: 比如event对象、其他参数

情况一: 获取event对象 很多时候我们需要拿到event对象来做一些事情(比如阻止默认行为),那么默认情况下,event对象有被直接传入,函数就可以获取到event对象

情况二:获取更多参数 有更多参数时,我们最好的方式就是传入一个箭头函数,主动执行的事件函数,并且传入相关的其他参数

event传递

我们只要利用上述解决this的第三种方法,就可以很容易的实现event参数的传递。

class App extends React.Component {
  constructor() {
    // ...
  }

  foo(event) {
    console.log('foo click', this, event);
  }

  render() {
    return (
      <div>
        // ...
        {/* 1.event参数传递 */}
        <button onClick={(event) => this.foo(event)}>foo点击</button>
      </div>
    )
  }
}

额外参数传递

只要利用箭头函数,就能实现额外参数的传递。

class App extends React.Component {
  constructor() {
    // ...
  }

  bar(event, age, name) {
    console.log('foo click', this, event, age, name);
  }

  render() {
    return (
      <div>
        // ...
        {/* 2.额外参数传递 */}
        <button onClick={(event) => this.bar(event, 'karl', 23)}>bar点击</button>
      </div>
    )
  }
}

React条件渲染

某些情况下,界面的内容会根据不同的情况显示不同的内容,或者决定是否渲染某部分内容,在vue中,我们会通过指令来控制,比如v-if、v-show;在React中,所有的条件判断都和普通的JavaScript代码一致

因此常见的条件渲染的方式有:

  • 方式一: 条件判断语句,适合逻辑较多的情况
  • 方式二: 三元运算符,适合逻辑比较简单
  • 方式三: 逻辑与&&

使用if进行条件判断

class App extends React.Component {
  constructor() {
    super();

    this.state = {
      isReady: true
    }
  }

  render() {
    const { isReady }=this.state;

    let showElement = null;
    if(isReady) {
      showElement = <button>开始</button>
    } else {
      showElement = <p>结束</p>
    }

    return (
      <div>
        <div>{showElement}</div>
      </div>
    )
  }
}

使用三元运算符

class App extends React.Component {
  constructor() {
    super();

    this.state = {
      isReady: true
    }
  }

  render() {
    const { isReady }=this.state;
    return (
      <div>
        <div>{ isReady ? <button>开始</button> : <p>结束</p> }</div>
      </div>
    )
  }
}

3.逻辑与&&

class App extends React.Component {
  constructor() {
    super();

    this.state = {
      friend: {
        name: 'karl',
        job: 'front end'
      }
    }
  }

  render() {
    const { friend }=this.state;

    return (
      <div>
        <div>{ friend && <p>{friend.name + ": " + friend.job}</p> }</div>
      </div>
    )
  }
}

条件渲染小案例

实现的效果如下:

屏幕录制2023-05-15 23.03.32.gif

其实逻辑也不难,实现的方法也有很多,看自己喜欢怎么写吧:

class App extends React.Component {
  constructor() {
    super();

    this.state = {
      message: '条件渲染小案例',
      content: null
    }
  }

  show() {
    this.setState({
      content: this.state.content ? null : <p>我显示出来啦</p>
    });
  }

  render() {
    const { message, content }=this.state;

    return (
      <div>
        <h2>{message}</h2>
        <button onClick={() => this.show()}>toggle</button>
        <div>{content}</div>
      </div>
    )
  }
}

这里的代码相当于Vue的v-if,其实也可以实现出v-show来减小性能开销。

写在最后

如果大家喜欢的话可以收藏本专栏,之后会慢慢更新,然后大家觉得不错可以点个赞或收藏一下 🌟。

本节的源码放在作者的GitHub仓库里,分别是: