React17在我看来是这样的

简介: 本文适合觉得React难学,或者想重头系统化学习React的小伙伴。

一、前言


本文基于开源项目:

https://github.com/facebook/react

 

 广东靓仔总结下自己这几年对学习前端框架的一些想法,顺便讲讲React17带来的改变引起的一些个人想法。  

 

在我们学习一门前端框架的时候,广东靓仔觉得官方文档一定是最好的学习资料。有些小伙伴可能把官方文档当作入门指南,然后再找其他学习资料去深度学习。广东靓仔觉得有点舍近求远了,官方文档一定是开发人员尽可能去写全、写精的。我们应该仔细的去阅读,而不是粗略看了一遍,然后找各种文章去阅读学习。


  在这里广东靓仔可以很负责的说一句,市面上80%免费的文章,基本都是基于官方文档来写的。广东靓仔的文章也是如此,只不过是加了点自己的思考。


   React官方文档写得特别好,还带着我们去领悟它的设计模式。


1.1 没有React基础可以开始用React17吗?

在React16.8版本引入了hook以来,React的学习成本就已经降低了很多了,我们可以通过函数式编程来开发我们的应用。React以前就像一艘“航母”一样,大而全。正因“全”因此我们的学习成本自然就高。有了hook我们使用函数组件开发,上手难度自然降低了很多。


二、React 17 带来了哪些改变


   React17.0.1版本相对与16.8版本本身没有增加新特性,只是做了一些补充。17版本更像一个 基石 ,为什么这么说呢?细心的小伙伴们会发现官方描述了这么一句话:“React v17 开启了 React 渐进式升级的新篇章”。这句话我看出了雄心勃勃,后续 18、19 等的更新版本一定是以17这个“基石”来开启新篇章。

这里列举让广东靓仔眼前一亮的两点:

1、新的 JSX 转换逻辑

2、事件系统重构


当然React17也有其他的更新,大家有兴趣可以去看官方文档。


三、重构 JSX 转换逻辑


React17之前我们如果这样写,代码如下:


function MyComponent() {
  return <p>前端早茶</p>
}


页面是会报错的,why?


上一篇文章有讲到React 中对 JSX 代码的转换依赖的是 React.createElement 这个函数。有兴趣可以回头看下上一篇文章。


因此在写JSX的时候,是一定要在头部引入React的,代码如下:

import React from 'react';
function MyComponent() {
  return <p>前端早茶</p>
}


React17之后我们在使用JSX,不再需要引入import React from 'react'; 


React17中编译器会自动帮我们引入 JSX 的解析器的,例如:


function MyComponent() {
  return <p>前端早茶</p>
}


这个代码最后会被编译器转换为:

import {jsx as _jsx} from 'react/jsx-runtime';
function MyComponent() {
  return _jsx('p', { children: '前端早茶' });
}


react/jsx-runtime 中的 JSX 解析器帮我们完成了JSX的编译工作,很明显降低了我们的学习成本。如果有的小伙伴一开始就是从React17开始学习的,我们无感知的使用到它的方便。关于这块的内容,详细可以看看如下内容:

https://github.com/reactjs/rfcs/blob/createlement-rfc/text/0000-create-element-changes.md#motivation


四、事件系统重构


React17版本中事件系统重构可以分为两块来看:

  • 放弃document 来做事件的中心化管控
  • 放弃事件池

  • 4.1 卸掉历史包袱

   React之前是将所有事件冒泡到 document 来实现对事件的中心化管控,17版本放弃 document 来做事件的中心化管控。   why?因为有些时候合成事件虽然在 React 事件体系下的冒泡被阻止了,但是并不能够阻止原生 DOM 事件的冒泡。 


  React17中,事件管控相关的逻辑被转移到了每个 React 组件自己的容器 DOM 节点中,比如我们常写的在 ID 为 root 的 DOM 节点下挂载了一个 React 组件,代码如下:


const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

之后React 组件就只能自己管理自己的东东了,无法再影响到全局了。

 

  4.2 拥抱新潮流

   React 之前,合成事件对象都是被放进“事件池”统一管理,为了能够对事件对象的复用,提高性能。细心的小伙伴会发现,既然考虑到复用,事件处理函数执行完成后,合成事件对象内部的所有属性都会被置空。  


那么问题来了,如果事件执行完成,我们想获取事件对象呢?


   广东靓仔找来了官方的代码,来说明:

function handleChange(e) {
  // This won't work because the event object gets reused.
  setTimeout(() => {
    console.log(e.target.value); // Too late!
  }, 100);
}

异步执行的 setTimeout 回调会在 handleChange 这个事件处理函数执行完毕后执行,因此它拿不到想要的那个事件对象 e了。


要想获取的话,我们就需要使用e.persist() ,代码如下:


function handleChange(e) {
  // Prevents React from resetting its properties:
  e.persist();
  setTimeout(() => {
    console.log(e.target.value); // Works
  }, 100);
}


React 17在研发体验上考虑比较多,官方放弃事件池,为每一个合成事件创建新的对象。所以之后我们不再需要编写 e.persist(),也可以随时随地访问我们想要的事件对象。


五、总结


   在我们阅读完官方文档后,我们一定会进行更深层次的学习,比如看下框架底层是如何运行的,以及源码的阅读。  

 

这里广东靓仔给下一些小建议:

  • 在看源码前,我们先去官方文档复习下框架设计理念、源码分层设计
  • 阅读下框架官方开发人员写的相关文章
  • 借助框架的调用栈来进行源码的阅读,通过这个执行流程,我们就完整的对源码进行了一个初步的了解
  • 接下来再对源码执行过程中涉及的所有函数逻辑梳理一遍
相关文章
|
3月前
|
Web App开发 前端开发 JavaScript
React 之 requestIdleCallback 来了解一下
React 之 requestIdleCallback 来了解一下
107 0
|
16天前
|
前端开发 JavaScript 开发者
|
16天前
|
前端开发 JavaScript 算法
|
1月前
|
前端开发 JavaScript 编译器
使用React
使用React
13 0
|
4月前
|
存储 前端开发 JavaScript
对于React的了解与认识
对于React的了解与认识
|
5月前
|
前端开发 JavaScript 容器
React Portals
React Portals
56 0
|
11月前
|
前端开发 JavaScript
React 特点
React 特点
121 0
|
前端开发 调度
一篇必看的React文章
本文适合有 React 基础的小伙伴进阶学习
一篇必看的React文章
|
资源调度 前端开发 JavaScript
React 的 what,why 和 how
React 是一个用于构建用户界面的JavaScript 库。 用户界面:HTML 页面(前端) React 主要用来写 HTML 页面,或构建 Web 应用。 如果从 MVC 的角度来看,React 仅仅是视图层(V),也就是只负责视图的渲染,而并非提供了完整的 M 和 C 的功能。
75 0
|
前端开发 JavaScript API
REACT
开始 这是一个 React 文档及相关资源的概览页面。 React 是一个用于构建用户界面的 JavaScript 库。你可以在首页或教程中学习什么是 React。
139 0