前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >react冷门小知识

react冷门小知识

作者头像
娜姐
发布2021-03-04 10:33:57
4440
发布2021-03-04 10:33:57
举报
文章被收录于专栏:娜姐聊前端娜姐聊前端

1. react合成事件 SyntheticEvent

React在原生的DOM事件上封装了一层,称为SyntheticEvent(合成事件)。所有事件都会冒泡到根节点上,然后进行后续处理。

  • 优势1:兼容各类浏览器的Dom事件
  • 优势2:事件池。

事件池中装满了SyntheticEvent对象,需要时池中取出使用,用完后再放回池中,这就意味着 SyntheticEvent对象可以被缓存且反复使用。目的是提高性能,减少创建不必要的对象。

当调用事件回调函数之后,合成对象上的所有属性重置为null,但是合成事件对象依旧存在。

因此,写React事件回调函数的时候不能将 event 用于异步操作 —— 当异步操作真正执行的时候,SyntheticEvent对象有可能已经被重置了。

代码语言:javascript
复制
import React, { Component } from "react";

class TextInput extends Component {
  state = {
    counter: 0,
    value: this.props.defaultValue,
  }
  // 由于 setState 是异步操作,event.target.value 在运行时可能已经被重置了
  handleChange = event => 
    this.setState(prevState => ({ value: event.target.value, counter: prevState.counter + 1 }));

  render() {
    return (
      <span>Edited {this.state.editionCounter} times</span>
      <input
        type="text"
        value={this.state.value}
        onChange={this.handleChange} // WRONG!
      />
    )
  }
}

一般有两种解法:

  1. 使用 event.persist() 持久化合成事件:将当前event挪出事件池,从而该event属性值可以一直存在而不会被重置。
    • 缺点:放弃了SyntheticEvent事件复用能力,不推荐
  2. 缓存所需的event属性值
    • 缺点:代码略啰嗦。但是,推荐
代码语言:javascript
复制
import React, { Component } from "react";

class TextInput extends Component {
  state = {
    counter: 0,
    value: this.props.defaultValue,
  }
  
  handleChange = event => {
    const value = event.target.value; // value这个本地变量已经保存了目标值
    this.setState(prevState => ({ value, editionCounter: prevState.counter + 1 }));
  }

  render() {
    return (
      <span>Edited {this.state.editionCounter} times</span>
      <input
        type="text"
        value={this.state.value}
        onChange={this.handleChange}
      />
    )
  }
}

如要想要阻止冒泡,不要直接调用原生e.stopPropagation()方法,没用的。 利用合成事件上的nativeEvent访问到原生事件,再调用nativeEvent.stopImmediatePropagation方法。 https://developer.mozilla.org/zh-CN/docs/Web/API/Event/stopImmediatePropagation

2. 加了key就一定好吗?(此知识点React和Vue通用)

渲染列表时,大家都知道要加key值,为什么呢?为了配合diff算法做性能优化呀?

那么如果是纯文字改动呢?

代码语言:javascript
复制
<ul>
<li id="1">1</li>
<li id="2">2</li>
<li id="3">3</li>
<li id="4">4</li>
</ul>

// 更新为
<ul>
<li id="1">1</li>
<li id="2">3</li>
<li id="3">4</li>
<li id="4">5</li>
</ul>

如果指定了key,需要做移动,删除,新增,三种操作。但是,我们仅仅更新个textContent,需要这么大动作吗? 那就不要指定key好了,React(或者Vue)会复用原DOM节点,只做textContent更新而已,性能明显更好。

当然,如果节点上绑定了事件,且事件和节点内容相关,那么请务必小心,为了不必要的Bug,还是建议加上key

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. react合成事件 SyntheticEvent
  • 2. 加了key就一定好吗?(此知识点React和Vue通用)
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档