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

完 !

相关推荐
Martin -Tang24 分钟前
vite和webpack的区别
前端·webpack·node.js·vite
迷途小码农零零发25 分钟前
解锁微前端的优秀库
前端
王解1 小时前
webpack loader全解析,从入门到精通(10)
前端·webpack·node.js
老码沉思录1 小时前
写给初学者的React Native 全栈开发实战班
javascript·react native·react.js
老码沉思录1 小时前
React Native 全栈开发实战班 - 第四部分:用户界面进阶之动画效果实现
react native·react.js·ui
我不当帕鲁谁当帕鲁1 小时前
arcgis for js实现FeatureLayer图层弹窗展示所有field字段
前端·javascript·arcgis
那一抹阳光多灿烂1 小时前
工程化实战内功修炼测试题
前端·javascript
放逐者-保持本心,方可放逐2 小时前
微信小程序=》基础=》常见问题=》性能总结
前端·微信小程序·小程序·前端框架
毋若成4 小时前
前端三大组件之CSS,三大选择器,游戏网页仿写
前端·css
红中马喽4 小时前
JS学习日记(webAPI—DOM)
开发语言·前端·javascript·笔记·vscode·学习