React v17有什么新功能?

发布于 / 学习

前言

自从 React v16 首次发布以来已经过去了大约三年的时间,等待下一个主要版本的发布已经结束了。React 团队承诺 v17 版本的发布对未来非常重要,但也提到没有添加新特性。你可能想知道它为什么会被发布。

在本文中,我将列出最新版本中所做的更改。

正文

为什么没有新功能?

React 17 主要专注于使 React 本身更容易升级。尽管在这次更新中没有直接面向开发人员的功能是很不寻常的,但这次发布的主要目标是确保将一个版本的React管理的树嵌入到另一个版本的React管理的树中是安全的。React 开发人员团队将此称为“垫脚石”版本。https://reactjs.org/blog/2020/08/10/react-v17-rc.html

逐步升级

这些年来,React 升级要么全有要么全无。您要么必须继续使用旧版本,要么需要将整个应用程序升级到新版本。因此,如果新更新中引入了重大更改,并且您打算迁移到新版本,则必须更改代码库,尤其是在代码库很大的情况下。

React 团队已使用React 17 解决了这些问题中的大多数问题。当 React v18 和以下版本推出时,您可以通过升级应用程序的某些部分来逐步迁移,同时仍然让其他部分在 React v17 上运行。因此,如果您的大型应用程序使用的版本未得到积极维护,则此选项将非常有用。

React 的团队已经准备了一个仓库来演示如何延迟加载旧版本的 React

https://github.com/reactjs/react-gradual-upgrade-demo/

对事件委托的更改

“在React 17中,React将不再在该document级别附加事件处理程序。而是将它们附加到根树容器中,以生成您的React树。https://reactjs.org/blog/2020/10/20/react-v17.html

让我们看一个例子。考虑将onClick事件附加到React中的按钮,如下所示:

<button onClick = {handleClick}>

与上面的代码等效的原始JS看起来像这样:

myButton.addEventListener('click',handleClick);

然后,React 将每种事件类型的一个处理程序直接附加到文档节点,而不是将其附加到声明它们的 DOM 节点。这称为事件委托。

React v17 中,事件处理程序将不再附加在文档级别,而是将它们附加到呈现树的 DOM 容器中。

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

通过 React v17 的这一更改,现在可以安全嵌套使用不同版本的 React 构建的应用程序。

新的JSX转换

尽管升级到此新转换完全是可选的,但 React v17提供了新的 JSX Transform重写版本。它仍然提供一些好处,例如:

  • 您不需要导入 React
  • 改善捆绑包尺寸

如果您想阅读更多有关此新转换的信息,请查看React团队的这篇博客文章:https://reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html

重大变化(Breaking Changes)

此新版本附带一些重大更改。

事件委托

如上所述,升级后可能会遇到一些问题。

在此新版本中,event.stopPropagation() 实际上会阻止你的文档处理程序释放

document.addEventListener('click', function() {
  //此自定义处理程序将不再
  //来自调用e.stopPropagation()的React组件的点击
});

要解决此问题,请 capture 通过将 { capture: true }选项作为第三个参数传递,将事件侦听器转换为使用阶段,如下所示:

document.addEventListener('click',function(){ 
  //现在此事件处理程序使用捕获阶段,
  //因此它接收下面的* all * click事件!
},{capture:true});

这样,我们看到事件委托现在比以往任何时候都更接近正常的 DOM

与浏览器保持一致

React 对事件系统进行了一些更改:

  • onScroll 事件不再产生冒泡
  • onBluronFocus 事件现在已经切换到使用本地 focusinfocusout 内部事件,更好地匹配 React 现有的行为,甚至提供更多的信息。
  • onClickCapture 现在利用实际的浏览器捕获阶段侦听器。

没有事件处理池

在这个版本中,事件池优化已经从 React 中删除,这是由于它非常混乱以及并没有提高性能

function handleChange(e) {
  setData(data => ({
    ...data,
    // This crashes in React 16 and earlier:
    text: e.target.value
  }));
}

React 17 中,此代码可以按您期望的那样工作。旧的事件池优化已被完全删除,因此您可以在需要时阅读事件字段

Effect 清理时机

这个新版本还使 useEffect 钩子清理函数的定时更加一致

useEffect(() => {
  // This is the effect itself.
  return () => {    
  // This is its cleanup.  
  };
});

React v16 版本中,Effect 清理是同步操作,根据 React 博客的说法,在 React v17 中,Effect 清除功能始终异步运行。例如,如果要卸载组件,则在更新屏幕后运行清除。

函数 undefined 返回一致的错误

这句话怎么解释呢,在 React v16 中,返回 undefined 的函数总是会抛出错误,这主要是因为经常无意中造成返回 undefined

如:

function Button(){ 
  //我们忘记写return,因此该组件返回undefined。
  // React将其表面化为错误而不是忽略它。
  <button />; 
}

最初,这种行为只适用于类和函数组件,但是在新版本中,forwardRef memo 组件也加入了这个功能,使它们的行为与常规的类和函数组件一致,请注意,如果您故意不进行任何渲染,该实例将返回 null

结论

尽管 React v17 没有提供任何新功能,但它通过直接解决升级体验,并使 React 的行为更接近现代浏览器,为即将到来的版本奠定了坚实的基础

本文翻译自 What’s New in React v17?

本文采用 CC BY-NC-SA 3.0 Unported 协议进行许可
本文链接: https://www.ahwgs.cn/react-v17youshenmexingongneng.html