从React 15到React 16

2019-09-16 admin

就像人们对移动应用程序和操作系统的更新感到兴奋一样,开发人员也应该对使用的框架更新感到兴奋。 各个框架的新版本给我们带来开箱即用的新功能和技巧。

以下是将现有应用从React 15迁移到React 16时应考虑的一些优秀功能。

我们是时候对React15说再见了 👋

错误处理

React 16 引入了错误边界的新概念。

错误边界是捕获子组件树中任意位置javascript错误的react组件。他们记录这些错误,并且渲染备用的UI,而不是崩溃的组件树。错误边界可以在渲染期间,生命周期方法,以及它们下面的整个树的构造函数中捕获错误。

如果一个类组件定义一个名为componentDidCatch(error, info)的新生命周期方法,那么它将变成错误边界:

class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }

  componentDidCatch(error, info) {
    // Display fallback UI
    this.setState({ hasError: true });
    // You can also log the error to an error reporting service
    logErrorToMyService(error, info);
  }

  render() {
    if (this.state.hasError) {
      // You can render any custom fallback UI
      return <h1>Something went wrong.</h1>;
    }
    return this.props.children;
  }
}

接下来,你可以把它当做一个普通的组件来用。

<ErrorBoundary>  
   <MyWidget />
</ErrorBoundary>

componentDidCatch()方法的工作类似于JavaScript catch {}块,但对于组件。只有类组件可以是错误边界。实际上,大多数情况下,您只需要声明一次错误边界组件。然后你就可以在整个应用程序中使用它。

需要注意的是,错误边界只捕获其下面组件的错误。错误边界不能够捕获自身的错误,如果错误边界尝试渲染错误信息失败,那么错误将传播到其上方最近的错误边界,这一点,也类似于catch{}块在javaScript中的工作方式。

查看一个演示: https://codepen.io/gaearon/pe… 有关错误处理的更多信息,可访问error-handling-in-react-16

新的渲染返回类型: fragments(片段)和strings(字符串)

摆脱渲染时将组件包裹在div中。 您现在可以在component的render方法返回一个元素数组。与其他数组一样,您需要为每个元素添加一个key以避免报key警告:

render() {
  // No need to wrap list items in an extra element!
  return [
    // Don't forget the keys :)
    <li key="A">First item</li>,
    <li key="B">Second item</li>,
    <li key="C">Third item</li>,
  ];
}

React 16.2.0开始,fragments支持JSX的特殊片段语法,不需要key。

支持返回字符串:

render() {
  return 'Look ma, no spans!';
}

Portals

Portals提供了一种将子项渲染在父组件的DOM层次结构之外的DOM节点中的好方法。

ReactDOM.createPortal(child, container)

其中,第一个参数child是任何可渲染的react元素,例如元素,字符串,或者片段。第二个参数container是dom元素

怎样使用它

当我们从组件的render方法返回一个元素时,它作为最近父节点的子节点挂载到DOM中:

render() {
  // React mounts a new div and renders the children into it
  return (
    <div>
      {this.props.children}
    </div>
  );
}

有时,将子节点插入DOM中的其他位置是很有用的:

render() {
  // React does *not* create a new div. It renders the children into `domNode`.
  // `domNode` is any valid DOM node, regardless of its location in the DOM.
  return ReactDOM.createPortal(
    this.props.children,
    domNode
  );
}

portals的一个典型用例是当父组件具有overflow:hidden或z-index样式时,但是您需要子容器在视觉上“突破”其容器。例如,对话框,hover悬停卡片和tooltip。 https://codepen.io/gaearon/pe…

自定义DOM属性

React 15用于忽略任何未知的DOM属性。因为React不识别它,会跳过它们。

// Your code:
<div mycustomattribute="something" />

使用React 15会渲染一个空div:

// React 15 output:
<div />

在react16中,输出将会是下面这样子(自定义属性将会显示且不会被忽略)

// React 16 output:
<div mycustomattribute="something" />

通过设置state为NULL来避免重复渲染

使用React16,您可以直接从setState()阻止state更新和重新渲染。你只需要让你的函数返回null。

const MAX_PIZZAS = 20;

function addAnotherPizza(state, props) {
  // Stop updates and re-renders if I've had enough pizzas.
  if (state.pizza === MAX_PIZZAS) {
    return null;
  }

  // If not, keep the pizzas coming! :D
  return {
    pizza: state.pizza + 1,
  }
}

this.setState(addAnotherPizza);

访问Refs

将ref传递给render中的元素时,可以在ref的当前属性中访问对该节点的引用。

const node = this.myRef.current;

ref的值根据节点的类型而有所不同

  • 当在HTML元素上使用ref属性时,在构造函数中使用React.createRef()创建的ref将接收底层DOM元素作为current属性。
  • 当ref属性用于自定义组件时,ref对象接收组件的挂载实例作为current。
  • 您不能函数组件上使用ref属性,因为它们没有实例。

关于refs,更多

Context

Context提供了一种通过组件树传递数据的方法,而无需逐级通过props传递。

React.createContext

const {Provider, Consumer} = React.createContext(defaultValue);

创建{Provider,Consumer}。当React渲染上下文Consumer时,它将从树中它上面最接近的匹配Provider读取当前上下文值。 defaultValue参数仅在Consumer在树中没有匹配的Provider时使用。这可以让我们不包装它们就能单独测试组件。注意:将undefined作为Provider值传递不会导致Consumer使用defaultValue。

Provider

<Provider value={/* some value */}>

一个React组件,允许消费者订阅上下文更改。接受一个value prop,传递给作为此Provider的后代的消费者。一个Provider可以连接到许多消费者,可以嵌套覆盖树中更深层的值。

Consumer

<Consumer>
  {value => /* render something based on the context value */}
</Consumer>

一个订阅上下文更改的React组件。

需要一个函数作为子元素。该函数接收当前上下文值并返回React节点。传递给函数的value参数将等于树中上述此上下文的最近Provider的value prop。如果上面没有此上下文的Provider,则value参数将等于传递给createContext()的defaultValue。

React生命周期钩子

clipboard.png

这些是使用React16时一定要尝试的一些功能!

[转载]原文链接:https://segmentfault.com/a/1190000020397148

本站文章除注明转载外,均为本站原创或编译。欢迎任何形式的转载,但请务必注明出处。

转载请注明:文章转载自 JavaScript中文网 [https://www.javascriptcn.com]

本文地址:https://www.javascriptcn.com/read-75263.html

文章标题:从React 15到React 16

相关文章
Facebook发布React Native!
React.js Conf 2015会议上,Facebook发布了React Native。 React.js 是 Facebook 推出的一个用来构建用户界面的 JavaScript 库。 React中,把一切东西都看成组件,而且所有组件...
2015-11-12
可以从CSS框架中借鉴到什么
现在很多人会使用 CSS 框架进行快速建站。   那 CSS 框架是什么呢,它通常是一些 CSS 文件的集合,这些文件包括基本布局、表单样式、网格、简单组件、以及样式重置。使用 CSS 框架大大降低工作成本进行快速建站。   当然对于一些大...
2016-03-11
React Native 用JavaScript编写原生ios应用
ReactNative 可以基于目前大热的开源JavaScript库React.js来开发iOS和Android原生App。而且React Native已经用于生产环境——Facebook Groups iOS 应用就是基于它开发的。 Re...
2015-11-12
HTML5游戏2015年的开发趋势
在互联网行业中,一个行业从零到成熟,开发者生态也是对应的,我们今年看到很多大公司,包括像微软和Google,也参与到了HTML5 开发者生态的建设当中。关于HTML5移动游戏的开发和盈利生态的走向又该去往何处?下面我们来试着讨论一下。 《围...
2015-11-12
从 Node.js 分裂出 Io.js 事件看开源软件谁做主
Node.js 作为服务器编程语言的后起之秀,常用来构建和运行 Web 应用,近日却爆出其社区出现分裂。由于对官方运营商 Joyent 公司在 Node.js 管理上的长期不满,多位核心开发者另立门户,创建了分支 Io.js。从 GitHu...
2015-11-12
从 JavaScript 到 TypeScript - 声明类型
从 JavaScript 语法改写为 TypeScript 语法,有两个关键点,一点是类成员变量 (Field) 需要声明,另一点是要为各种东西 (变量、参数、函数 / 方法等) 声明类型。而这两个点直接引出了两个关键性的问题,有哪些类型?...
2017-06-05
[翻译]基于Webpack4使用懒加载分离打包React代码
原文地址:https://engineering.innovid.com/code-splitting-using-lazy-loading-with-react-redux-typescript-and-webpack-4-3ec601...
2018-03-11
2015 Web 2.0和AJAX如何做好优化
2015如何让做好web2.0和ajax的优化?JavaScript中文网总结当下提出以下四大优化意见,旨在帮助W前端开发人员有效利用APM解决上述问题。 随着Web应用程序速度与效率快速增长,网站已经成为企业与其客户进行交互的第一途径——...
2015-11-12
2015年将会有大量基于HTML5和JS的WEB应用
随着HTML5的定稿,以及JS的迅速发展,我们有理由相信,在接下来的一年里,将会涌现出大量的WEB应用,网站的表现形式将不再仅仅局限于过去的形式,必将在2015年引来一次重大改革! ...
2015-11-12
2015年2月国内操作系统市场份额概况,xp占46.29%,
规则调整:2012年6月1日开始,Mac操作系统中不再包含ipad、iphone市场份额。 ...
2015-11-12
回到顶部