新版React官方文档解读(八)- react API 之 startTransition、 createContext 和 lazy

大家好呀,我是小肚肚肚肚肚哦!这是我的React官网解读系列!

React 官网 beta 版本已经变为了正式版,但仍旧没有中文版。对于国内不少开发者来说增加了不少麻烦。我这里以前端开发的角度归纳总结一下,把其中大家重点使用的部分介绍给大家。

官网地址:React


startTransition

我们在讲 useTransition 的一节我们讲过,通过 hook 可以获取到这个 API,推荐结合 hook 一起使用。

当然也可以直接引入:

js 复制代码
import { startTransition } from 'react';

function TabContainer() {
  const [tab, setTab] = useState('about');

  function selectTab(nextTab) {
    startTransition(() => {
      setTab(nextTab);
    });
  }
  // ...
}

他的作用是防止 UI 阻塞,做到前端异步非阻塞渲染。具体使用方式见 useTransition。

注意事项

Caveats

  • startTransition 不会追踪渲染 pending 的状态. 想要获取渲染实时状态,请使用 useTransition .
  • 使用它包裹 state 的 set 函数来实现跟该 state 相关的渲染过渡。 如果想要响应2 props 变化来实现渲染过渡,请使用 useDeferredValue.
  • startTransition 内部函数必须是同步的.
  • 标记为 transition 的 state 更新会被其他 state 的更新打断渲染,在其他渲染调度结束后再次想重新执行该渲染.
  • 不能用于控制文本输入组件.
  • 如果同时有多个在运行的过渡,React 会把他们合并一起处理。这个方案似乎是个性能缺陷,随后的版本可能会修复它。

createContext

顾名思义,就是创建一个 context 对象,一般结合 hook 一起使用,可以参考我 useContext 的文章。

官网的部分描述与 useContext 有重复,这里及直接讲使用案例。

使用案例

  1. 配置全局变量
js 复制代码
// 放在全局,创建时的默认值一般可以不用传递,在 provider 时会配置初始值的
const ThemeContext = createContext();  
const AuthContext = createContext();

我们定义主题信息和认证信息,用它包裹根组件:

jsx 复制代码
const [theme, setTheme] = useState('dark');
const [currentUser, setCurrentUser] = useState({ id: 1 });

<ThemeContext.Provider value={theme}>
  <AuthContext.Provider value={currentUser}>
    <Page />
  </AuthContext.Provider>
</ThemeContext.Provider>

在包裹的内部组件中,无论多深的层级,都可以这样使用来获取 value 值:

js 复制代码
const theme = useContext(ThemeContext); // dark

确保 ThemeContext 是一开始定义的那个单例

他踢动了一个单向数据流,可以从顶向下传递动态响应式数据。如果在入口处维护一些 state,暴露出事件来给各个业务模块调用,就可以实现一个类似 redux 的功能。

  1. 局部引用
js 复制代码
// Button.js  
import { ThemeContext } from './Contexts.js';

比如上面的例子,我们全局配置了主题为 dark,但是有一个 Button 组件,其需要特殊处理,就可以这样写,在 Button 内部再次 Provider 自己想要的主题即可,相同的 context 遵循就近原则。

lazy

延迟加载组件的工具,往往与 <Suspense> 组件一起使用。

简单使用:

js 复制代码
const MarkdownPreview = lazy(() => import('./MarkdownPreview.js'));

接受参数

接受一个函数,返回 Promise 或者 其他类 thenable 的异步函数。React 默认不会去加载 lazy 包裹的组件,除非明确的在界面上需要渲染他。当开始加载时,React 会等待其解析,解析过程中由 Suspense 提供过渡响应,解析完毕后即可渲染。返回的 Promise 和 Promise 中 resolve 的值都会被缓存(比如打包的js文件),再次渲染就不会重复请求资源。但是这个组件本身的重渲染还是会被触发。如果该 Promise reject 请求,异常会冒泡至最近的处理函数(Error Boundary)抛出。

返回值

返回一个可以渲染在 fiber 树中的组件。

注意事项

  • lazy 要在 js 模块顶层使用,不要在组件内部使用

使用案例

  1. 动态引入加载
js 复制代码
const MarkdownPreview = lazy(() => import('./MarkdownPreview.js'));

<Suspense fallback={<Loading />}>
  <h2>Preview</h2>
  <MarkdownPreview />
</Suspense>

效果:

加载中:

加载后:

加载一次后便不会再出现 loading

  1. 路由懒加载

介绍作者在工作中用过的一个使用 js 数组配置路由懒加载的案例:

jsx 复制代码
// route.js
const Loadable = (Component) => (props) => (
    <Suspense fallback={<Loader />}>
      <Component {...props} />
    </Suspense>
);

const Home = Loadable(lazy(() => import('views/pages')));
const User = Loadable(lazy(() => import('views/pages/common/user')));

const routes = [
    {
      path: 'home',
      children: [
        {
          path: '/',
          element: <Home />
        }
      ]
    },
    {
      path: 'setting',
      children: [
        {
          path: 'user-setting',
          element: <User />
        }
      ]
    }
]

useRoutes(routes);

// 使用
import Routes from 'route.js';

<Routes />

完 !

相关推荐
下雪天的夏风12 分钟前
TS - tsconfig.json 和 tsconfig.node.json 的关系,如何在TS 中使用 JS 不报错
前端·javascript·typescript
diygwcom23 分钟前
electron-updater实现electron全量版本更新
前端·javascript·electron
volodyan27 分钟前
electron react离线使用monaco-editor
javascript·react.js·electron
Hello-Mr.Wang40 分钟前
vue3中开发引导页的方法
开发语言·前端·javascript
程序员凡尘1 小时前
完美解决 Array 方法 (map/filter/reduce) 不按预期工作 的正确解决方法,亲测有效!!!
前端·javascript·vue.js
编程零零七4 小时前
Python数据分析工具(三):pymssql的用法
开发语言·前端·数据库·python·oracle·数据分析·pymssql
(⊙o⊙)~哦6 小时前
JavaScript substring() 方法
前端
无心使然云中漫步7 小时前
GIS OGC之WMTS地图服务,通过Capabilities XML描述文档,获取matrixIds,origin,计算resolutions
前端·javascript
Bug缔造者7 小时前
Element-ui el-table 全局表格排序
前端·javascript·vue.js
xnian_7 小时前
解决ruoyi-vue-pro-master框架引入报错,启动报错问题
前端·javascript·vue.js