关于react-native:在-React-Native-中原生实现动态导入

7次阅读

共计 5514 个字符,预计需要花费 14 分钟才能阅读完成。

在 React Native 社区中,原生动静导入始终是期待已久的性能。在 React Native 0.72 版本公布之前,只能通过第三方库和其余变通方法实现动静导入,例如应用 React.lazy()Suspense 函数。当初,动静导入曾经成为 React Native 框架的原生局部。

在这篇文章中,咱们将比拟动态和动静导入,学习如何原生地解决动静导入,以及无效施行的最佳实际。

动态导入 vs. 动静导入

在深入研究实现细节之前,了解什么是动静导入以及它们与动态导入有何不同是至关重要的,动态导入是在 JavaScript 中蕴含模块的更常见形式。

动态导入是你在文件顶部应用 importrequire 语法申明的导入。这是因为在应用程序启动时,它们可能须要在你的整个应用程序中可用。

这是一个例子:

import React from 'react';
import {View, Text} from 'react-native';
const MyComponent = require('./MyComponent');

动态导入是同步的,意味着它们会阻塞主线程,直到模块齐全加载。这种行为可能导致应用程序启动工夫变慢,特地是在较大的应用程序中。然而,当一个库或模块在代码库的多个工夫或多个中央须要时,动态导入就会显得十分有用。

相比之下,动静导入赋予开发者在须要时即时导入模块的能力,引领了一个异步范式。这意味着代码是按需加载的。

总的来说,动态导入和动静导入的次要区别在于,动态导入在编译时解析,而动静导入在运行时解析。

在 React Native v0.72 版本之前,动静导入并不是开箱即用的反对,因为它们与 Metro 打包器不兼容,Metro 打包器负责在 React Native 应用程序中打包 JavaScript 代码和资产。

Metro 打包器不容许任何运行时更改,并通过移除未应用的模块并用动态援用替换它们来优化包大小。这意味着 React Native 开发者必须依赖第三方库或自定义解决方案来在他们的利用中实现动静导入。咱们将在本文前面探讨这些。

如何在 React Native 中原生实现动静导入

要在 React Native 中 应用原生动静导入,你须要装置 0.72 或更高版本的 React Native。你能够通过在终端运行 npx react-native --version 来查看你的 React Native 版本。你还须要在你的我的项目中配置 0.66 或更高版本的 Metro 打包器。

React Native 中应用原生动静导入有两种形式:应用 import() 语法或应用 require.context() 办法。

应用 import() 语法

依据 Metro Bundler 官网文档:

import() 调用在开箱即用的状况下失去反对。在 React Native 中,应用 import() 会主动宰割你的利用程序代码,使其在开发过程中加载速度更快,而不影响公布构建。

import() 语法与动态 import 关键字类似,但你能够在代码的任何中央应用它,只有你解决好 promise 的解决和回绝。

例如,假如你有一个名为 SomeComponent 的组件,你心愿依据某些条件动静加载它。你能够像这样应用 import() 语法:

const loadSomeComponent = async () => {
  try {const SomeComponent = await import('./SomeComponent');
    // Do something with SomeComponent
  } catch (error) {// Handle error}
};

// Use SomeComponent conditionally
if (someCondition) {loadSomeComponent();
}

留神:你须要在 async 函数内应用 await 关键字来期待 promise 的解决。或者,你能够应用 .then().catch() 办法来解决 promise 的解决和回绝。

应用 require.context() 办法

require.context() 办法当初是 Metro 打包器的一个反对个性,容许你为动静导入创立一个上下文。这个个性是由 Evan Bacon 增加到 Metro 库中的。

context 是一个蕴含与给定模式匹配的一组模块或组件信息的对象。你能够应用 require.context() 办法来创立这样的上下文:

// Create a context for all components in the ./components folder
const context = require.context('./components', true);

require.context() 办法的第一个参数是你想要查找模块或组件的根底目录。第二个参数是一个布尔值,示意你是否想要蕴含子目录。

有了 require.context,你当初能够依据变量或正则表达式进行导入。

这是一个示例,展现了如何应用 require.context 从文件夹中导入所有图片并将它们显示在列表中:

// App.js
import React from 'react';
import {FlatList, Image, StyleSheet} from 'react-native';

// Import all the images from the assets/images folder
const images = require.context('./assets/images', true, /\.png$/);

// Create an array of image sources
const imageSources = images.keys().map((key) => images(key));

const App = () => {
  // Render each image in a flat list
  return (
    <FlatList
      data={imageSources}
      keyExtractor={(item) => item}
      renderItem={({item}) => <Image style={styles.image} source={item} />}
    />
  );
};

const styles = StyleSheet.create({
  image: {
    width: 100,
    height: 100,
    margin: 10,
  },
});

export default App;

React Native v0.72 引入了通过 require.context 办法反对动静导入,这与 webpack 提供的形式相似。

然而 require.context 始终以来都被 Expo 路由器在后盾应用,以依据文件目录构造和你领有的文件主动创立路由。它应用一个带有正则表达式的 require.context 调用,所有的路由都能够在运行时被确定。

例如,如果你有一个名为 app/home.tsx 的文件,它将变成一条门路为 /home 的路由。如果你有一个名为 app/profile/settings.tsx 的文件,它将变成一条门路为 /profile/settings 的路由。

例如,如果你有一个名为 app/home.tsx 的文件,它将成为一个门路为 /home 的路由。如果你有一个名为 app/profile/settings.tsx 的文件,它将成为一个门路为 /profile/settings 的路由。

因而,你无需手动定义或导入你的路由——Expo Router 会为你实现!

实现动静导入的第三方解决方案

应用 React.lazy() 和 Suspense

React.lazy()Suspense 是 React 的个性,容许你懒加载组件,也就是说,只有当它们被渲染时才会加载。你能够应用 React.lazy() 函数来创立一个包装动静导入的组件,你能够应用 Suspense 来显示一个备用组件,而动静导入正在加载。

这是一个例子:

import React, {lazy, Suspense} from "react";
import {Text, View} from "react-native";
import {styles} from "./styles";

const DynamicComponent = lazy(() => import("./DynamicComponent"));

function App() {
  return (<View style={styles.container}>
      <Suspense fallback={() => <Text>Loading ....</Text>}>
        <DynamicComponent />
      </Suspense>
    </View>
  );
}
export default App;

在你的 React Native 应用程序中,应用 React.lazy()Suspense 是实现动静导入的好办法。然而,须要留神的是 React.lazy() 是专门为 React 组件的代码宰割设计的。如果你须要动静导入非组件的 JavaScript 模块,你可能须要思考其余办法。

可加载组件

Loadable Components 是一种将你的 React Native 代码宰割成能够按需加载的小块的办法。在 React Native 中,你能够应用 react-loadable 库来动静加载和渲染组件。

import Loadable from 'react-loadable';

// Define a loading component while the target component is being loaded
const LoadingComponent = () => <ActivityIndicator size="large" color="#0000ff" />;

// Create a dynamic loader for the target component
const DynamicComponent = Loadable({loader: () => import('./YourComponent'), // Specify the target component path
  loading: LoadingComponent, // Use the loading component while loading
});

// Use the dynamic component in your application
function App() {
  return (
    <View>
      <DynamicComponent />
    </View>
  );
}

在这段代码中:

  • react-loadable 库中导入 Loadable 函数
  • 定义一个加载组件(例如,一个 ActivityIndicator),在指标组件加载时将会显示。
  • 应用 Loadable 函数创立一个动静组件。为 loader 属性提供一个导入指标组件的函数(将 './YourComponent' 替换为组件的理论门路),并指定 loading 属性以在加载过程中显示加载组件。
  • 最初,在你的利用的用户界面中应用 DynamicComponent。它将动静加载指标组件,并在准备就绪后显示它,同时显示加载组件。

这个库最后是为 React 网页利用设计的,所以它可能并不总是在 React Native 中运行得很好。

React Native 中动静导入的益处

动静导入为开发者提供了几个劣势:

  • 更快的启动工夫:通过只按需加载所需的代码,动静导入能够显著缩小你的利用启动所需的工夫。这对于提供晦涩的用户体验至关重要,尤其是在设施或网络较慢的状况下。
  • 进步代码可维护性:动静导入能够通过让你将不罕用的组件或库拆散到独自的模块中,更无效地组织你的代码库。这能够进步代码的可维护性,使得在你的利用的特定局部工作变得更容易。
  • 渐进式加载:动静导入反对渐进式加载。你能够优先加载要害组件,而不是强制用户期待整个应用程序的加载,同时在后盾加载主要性能。这确保了用户的初始体验无缝,同时你的应用程序的不太重要的局部在后盾加载,放弃用户的参与度。
  • 优化的包:动静导入容许你通过将它们宰割成更小、更易治理的块来优化你的 JavaScript 包。这能够导致包大小的减小,从而缩小应用程序的内存占用并减速加载过程。

应用动静导入的最佳实际

  • 审慎应用动静导入:动静导入并非能解决你所有性能和用户体验问题的灵丹妙药。它们带来了一些衡量,如减少的复杂性,潜在的谬误,以及对网络连接的依赖。因而,你应该只在必要时应用它们,而不是适度应用它们。
  • 应用加载指示器和占位符:加载指示器能够向用户显示利用正在动静加载一些模块以及须要多长时间。占位符能够向用户展现当模块加载实现后利用会是什么样子,并避免布局变动或空白空间。你能够应用像 ActivityIndicator 或 Skeleton 这样的 React Native 内置组件,或者像 react-native-loading-spinner-overlay react-native-skeleton-placeholder 这样的第三方库来实现这个目标。
  • 应用谬误边界和回退:在应用动静导入时,你应该应用谬误边界和回退来处理错误和失败。谬误边界是能够捕捉并解决其子组件中的谬误的组件。回退是在原始组件无奈加载或渲染时能够渲染的组件。你能够应用像 React 中的 ErrorBoundary 这样的内置组件,或者像 react-error-boundaryreact-native-error-boundary 这样的第三方库来实现这个目标。

总结

在这篇文章中,咱们学习了如何在 React Native 中应用原生动静导入。有了动静导入这个弱小的工具,你能够使你的 React Native 利用更高效、响应更快、用户体验更敌对。审慎应用动静导入并遵循最佳实际以确保无缝的用户体验是至关重要的。

正文完
 0