新版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 />

完 !

相关推荐
哀木1 小时前
一个简单的套壳方案,就能让你的 Agent 少做重复初始化
前端
问心无愧05131 小时前
ctf show web入门27
前端
小村儿1 小时前
给 AI Agent 装上"长期记忆":Karpathy 的 LLM Wiki 思想,我做成了工具
前端·后端·ai编程
竹林8181 小时前
用ethers.js连接MetaMask实现Web3钱包登录:从踩坑到稳定运行的完整记录
前端·javascript
heyCHEEMS1 小时前
如何用 Recast 实现静态配置文件源码级读写
前端·node.js
心连欣1 小时前
从零开始,学习所有指令!
前端·javascript·vue.js
review445432 小时前
大模型和function calling分别是如何工作的
前端
东东同学2 小时前
耗时一个月,我把 Nuxt 首屏性能排障经验做成了一个 AI Skill
前端·agent
冴羽3 小时前
超越 Vibe Coding —— AI 辅助编程指南
前端·ai编程·vibecoding
梦想的颜色3 小时前
一天一个SKILL——前端最佳自动化测试 webapp-testing
前端·web app