新版React官方文档解读(八)- react API 之 startTransition、 createContext 和 lazy
大家好呀,我是小肚肚肚肚肚哦!这是我的React官网解读系列!
React 官网 beta 版本已经变为了正式版,但仍旧没有中文版。对于国内不少开发者来说增加了不少麻烦。我这里以前端开发的角度归纳总结一下,把其中大家重点使用的部分介绍给大家。
startTransition
当然也可以直接引入:
import { startTransition } from 'react';
function TabContainer() {
const [tab, setTab] = useState('about');
function selectTab(nextTab) {
startTransition(() => {
setTab(nextTab);
});
}
// ...
}
他的作用是防止 UI 阻塞,做到前端异步非阻塞渲染。具体使用方式见 useTransition。
注意事项
Caveats
createContext
官网的部分描述与 useContext 有重复,这里及直接讲使用案例。
使用案例
- 配置全局变量
// 放在全局,创建时的默认值一般可以不用传递,在 provider 时会配置初始值的
const ThemeContext = createContext();
const AuthContext = createContext();
我们定义主题信息和认证信息,用它包裹根组件:
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 值:
const theme = useContext(ThemeContext); // dark
确保 ThemeContext 是一开始定义的那个单例
他踢动了一个单向数据流,可以从顶向下传递动态响应式数据。如果在入口处维护一些 state,暴露出事件来给各个业务模块调用,就可以实现一个类似 redux 的功能。
- 局部引用
// Button.js
import { ThemeContext } from './Contexts.js';
比如上面的例子,我们全局配置了主题为 dark,但是有一个 Button 组件,其需要特殊处理,就可以这样写,在 Button 内部再次 Provider 自己想要的主题即可,相同的 context 遵循就近原则。
lazy
简单使用:
const MarkdownPreview = lazy(() => import('./MarkdownPreview.js'));
接受参数
接受一个函数,返回 Promise 或者 其他类 thenable 的异步函数。React 默认不会去加载 lazy 包裹的组件,除非明确的在界面上需要渲染他。当开始加载时,React 会等待其解析,解析过程中由 Suspense 提供过渡响应,解析完毕后即可渲染。返回的 Promise 和 Promise 中 resolve 的值都会被缓存(比如打包的js文件),再次渲染就不会重复请求资源。但是这个组件本身的重渲染还是会被触发。如果该 Promise reject 请求,异常会冒泡至最近的处理函数(Error Boundary)抛出。
返回值
返回一个可以渲染在 fiber 树中的组件。
注意事项
- lazy 要在 js 模块顶层使用,不要在组件内部使用
使用案例
- 动态引入加载
const MarkdownPreview = lazy(() => import('./MarkdownPreview.js'));
<Suspense fallback={<Loading />}>
<h2>Preview</h2>
<MarkdownPreview />
</Suspense>
效果:
加载中:
加载后:
加载一次后便不会再出现 loading
- 路由懒加载
介绍作者在工作中用过的一个使用 js 数组配置路由懒加载的案例:
// 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 />
完 !
转载自:https://juejin.cn/post/7275225948454371368