React 的未来,与 Suspense 同行[每日前端夜话0x85]

栏目: 服务器 · 发布时间: 6年前

内容简介:作者:Lusan Das翻译:疯狂的技术宅来源:

每日前端夜话 0x85

每日前端夜话,陪你聊前端。

每天晚上18:00准时推送。

正文共:1693 字

预计阅读时间: 5 分钟

作者:Lusan Das

翻译:疯狂的技术宅

来源: logrocket

React 的未来,与 Suspense 同行[每日前端夜话0x85]

自从 React 团队发布他们的 16.x 愿景以来,已经风靡了整个社区。它添加了一些非常酷的东西:Hooks、惰性加载、Suspense 和缓存 API。

这不是又一篇关于如何编写 Hook 的文章,而是对 React 未来的期待!如果你从没有听说过 React Hooks 或其他新的 API,那么本文将会让你对 React 的未来感到兴奋。

随着文章的深入,我们将介绍两个新概念,预计它们将会在 2019 年第二季度发布:

  • 如何使用 Suspense 获取数据

  • 如何使用 react-cache

我已经很兴奋了!但是在我们进行深入探讨之前,先来快速回顾一下。

React Hooks

在 React 16.8 中,Hooks 正式成为稳定版本的一部分。它在高层次上解决了一些问题:

  • 由于有了用函数编写所有内容的概念,使得编写的代码更加模块化,更易于维护

  • 不鼓励使用 HOCs 和其他使代码难以理解的复杂功能

  • 放弃使用复杂的生命周期,如 componentDidMountcomponentDidUpdate 等,这会使我们写重复的代码

如果你想更详细地了解这些,请查看此处( https://reactjs.org/docs/hooks-intro.html#motivation )。

那么,让我们看一下 React Hooks 的演示以及典型应用的外观!

CodeSandbox上的演示:https://codesandbox.io/embed/3rm5jk86wm

React 的未来,与 Suspense 同行[每日前端夜话0x85]

CodeSandbox上的演示

React.lazy

这个名字真的是暴露了它的意图!当我们想对组件进行惰性加载时会需要它:

1const TodoList = React.lazy(() => import("./containers/todoList"));

在 webpack 动态导入的帮助下就可以做到这些,它有助于创建 bundles ,从而提高页面的加载速度。让我们做一个演示!回到前面 Codesandbox 的演示链接并将导入更改为以下内容:

1const TodoList = React.lazy(() => import("./containers/todoList"));
2const CompletedList = React.lazy(() => import("./containers/completedList"));
3const AddNewTask = React.lazy(() => import("./containers/addNewTask"));

请注意下图中独立的 bundle 是如何创建的!:smile:

React 的未来,与 Suspense 同行[每日前端夜话0x85]

用 Webpack 创建的Bundle

Suspense

Suspense 用起来相当简单。下面的代码可以帮你更好地理解这一点:

 1// https://codesandbox.io/s/new-6m2gj
 2import React, { useState, useEffect, Suspense } from "react";
 3import ReactDOM from "react-dom";
 4import todoListData from "./containers/todoList/todolistData";
 5import Header from "./containers/header";
 6import Clock from "./components/Clock";
 7import "./styles.css";
 8
 9const TodoList = React.lazy(() => import("./containers/todoList"));
10const CompletedList = React.lazy(() => import("./containers/completedList"));
11const AddNewTask = React.lazy(() => import("./containers/addNewTask"));
12
13function App() {
14  const { todolist } = todoListData;
15  const [todoListPayload, setTodoListPayload] = useState(todolist);
16  const [completedTodoList, setCompletedTodoList] = useState([]);
17
18  const addTodoTaskHandler = value => {
19    // addTodoTaskHandler
20  };
21
22  const removeTodoTaskHandler = ({ id }) => {
23    // Remove from the set of todo list
24  };
25
26  const completeTodoTaskHandler = ({ id }) => {
27    // Get item to remove
28  };
29
30return (
31    <div className="App">
32      <Header title={"My Tasks"} />
33      <Clock />
34      <div className="PageLayout">
35        <Suspense fallback={<div>Loading...</div>}>
36          <TodoList
37            payload={todoListPayload}
38            completeTodoTaskHandler={completeTodoTaskHandler}
39          />
40          <CompletedList list={completedTodoList} />
41          <AddNewTask addTodoTaskHandler={addTodoTaskHandler} />
42        </Suspense>
43      </div>
44    </div>
45  );
46}
47
48const rootElement = document.getElementById("root");
49ReactDOM.render(<App />, rootElement);

如果你想运行它的话,可以访问这个演示链接( https://codesandbox.io/s/new-6m2gj )。

如果我们检查演示中的代码,就会看到:

1<Suspense fallback={<div>Loading...</div>}>
2  <TodoList
3     payload={todoListPayload}
4     completeTodoTaskHandler={completeTodoTaskHandler}
5   />
6  <CompletedList list={completedTodoList} />
7  <AddNewTask addTodoTaskHandler={addTodoTaskHandler} />
8</Suspense>

它就像用 Suspense 包装组件一样简单。我们用 React.lazy() 懒加载了一些组件: TodoListCompletedListAddNewTask 。由于在内部它分别为每个组件生成 bundle,因此在网络较慢的条件下,可能需要一些时间去加载它们。

Suspense 将通过显示 fallback (例如 Loading … )或其他任何组件(如 spinner 或类似组件)来自动处理。

深入了解 React 的未来

前面的简短回顾已经令人非常激动了。现在让我们为 Suspense 带来更多乐趣。

Suspense 和 react-cache

等等,我们还没有讲到 Suspense ?那么如果我告诉你 Suspense 在调用 API 时也可以处理我们的加载状态呢?不过在此之前我们需要深入研究并更好地理解它。

经过一番挖掘和研究,我终于找到了  Shawn Swyx Wang:star2: 的 GitHub 存储库,我想直接引用他的文档( https://github.com/sw-yx/fresh-concurrent-react/blob/master/apis/react-suspense.md ):

React Suspense 是组件在从缓存加载数据时暂停渲染的通用方法。

它解决了当渲染是 I/O 绑定时的问题。

好的,“从缓存加载数据”给了我一个提示,但我需要更多关于如何真正处理API的信息。

Kent C. Dodds在他的 Egghead 课程( https://egghead.io/lessons/react-learn-fundamentals-of-react-suspense?pl=react-hooks-and-suspense-650307f2 )中讲授了一个重要概念:如果我们抛出一个 promise,Suspense 就会自动知道已经调用了一个 API 请求。

 1import React, { Suspense } from "react";
 2
 3fetchArticles() {
 4  // Some fetch API fetching articles
 5}
 6
 7let isRequestCalled = false;
 8function Content() {
 9  let result = [];
10  if (!cache) {
11    const promise = fetchArticles();
12    isRequestCalled = true;
13    throw promise; // Let suspense know
14  }
15  return <div>Article</div>;
16}
17
18const Articles = () => {
19  return (
20    <div>
21     {/* Yay promise is thrown */}
22      <Suspense fallback={<div>loading...</div>}>
23        <Content />
24      </Suspense>
25    </div>
26  );
27};
28
29export default Articles;

当然,这不是处理代码的最佳方式;它看起来有点麻烦。因此让我们试着用 react-cache 来更好地处理这些代码:

 1import React, { Suspense } from "react";
 2
 3import { unstable_createResource as createResource } from "react-cache";
 4
 5function fetchArticles() {
 6  // Some fetch API fetching articles
 7}
 8
 9const politicalArticles = createResource(fetchArticles);
10
11function Content() {
12  const result = politicalArticles.read(someKey);
13  return <div>Article</div>;
14}
15
16const Articles = () => {
17  return (
18    <div>
19      <Suspense fallback={<div>loading...</div>}>
20        <Content />
21      </Suspense>
22    </div>
23  );
24};
25
26export default Articles;

来自 react-cache 的 createResource 从回调中创建资源,并返回一个 promise。

好吧,为了让 Suspense 知道它必须显示加载状态,所需要的只是一个 promise。在 promise 解决之前,它将继续显示加载状态。

但是,这是实验性的。我相信你会遇到错误,所以不要担心,很明显 react-cache 仍处于开发阶段。

一点要小心,确保在组件内部使用 read 方法,否则,它会抛出一个错误。

 1// A snippet from the React-cache library
 2
 3function readContext(Context, observedBits) {
 4  const dispatcher = ReactCurrentDispatcher.current;
 5  if (dispatcher === null) {
 6    throw new Error(
 7      'react-cache: read and preload may only be called from within a ' +
 8        "component's render. They are not supported in event handlers or " +
 9        'lifecycle methods.',
10    );
11  }
12  return dispatcher.readContext(Context, observedBits);
13}

如果你有兴趣阅读 react-cache 源代码,请查看链接( https://github.com/facebook/react/blob/master/packages/react-cache/src/ReactCache.js)

恭喜!

现在我们抓住了 React 的不久的将来,有一件事是显而易见的:React 团队希望尽可能的简化 API。

我也对越来越多的库正朝着函数式编程的方向发展而感到兴奋。这种模式肯定会彻底改变我们编写前端的方式。我也在关注并发的 React —— 如果你有兴趣,请查看官方的路线图文档( https://reactjs.org/blog/2018/11/27/react-16-roadmap.html#react-16x-mid-2019-the-one-with-suspense-for-data-fetching )。 React-cache 和 Suspense 是并发 react 的一部分功能:sunglasses:。

原文:https://blog.logrocket.com/the-future-of-react-unfolding-with-suspense/

图书推荐

下面夹杂一些私货:也许你和高薪之间只差这一张图

2019年京程一灯课程体系上新,这是我们第一次将全部课程列表对外开放。

愿你有个好前程,愿你月薪30K。我们是认真的 ! React 的未来,与 Suspense 同行[每日前端夜话0x85]

React 的未来,与 Suspense 同行[每日前端夜话0x85]

在公众号内回复“体系”查看高清大图

长按二维码,加大鹏老师微信好友

拉你加入前端技术交流群

唠一唠怎样才能拿高薪

React 的未来,与 Suspense 同行[每日前端夜话0x85]

小手一抖,资料全有。长按二维码关注 前端先锋 ,阅读更多技术文章和业界动态。

React 的未来,与 Suspense 同行[每日前端夜话0x85]


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Foundations of PEAR

Foundations of PEAR

Good, Nathan A./ Kent, Allan / Springer-Verlag New York Inc / 2006-11 / $ 50.84

PEAR, the PHP Extension and Application Repository, is a bountiful resource for any PHP developer. Within its confines lie the tools that you need to do your job more quickly and efficiently. You need......一起来看看 《Foundations of PEAR》 这本书的介绍吧!

随机密码生成器
随机密码生成器

多种字符组合密码

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换