diff --git a/.gitignore b/.gitignore index 5c16a2e..a773e8c 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ node_modules docs/.vitepress/cache docs/.vitepress/dist +docs/Private diff --git a/docs/.vitepress/config.mts b/docs/.vitepress/config.mts index 6a038eb..08ae3f6 100644 --- a/docs/.vitepress/config.mts +++ b/docs/.vitepress/config.mts @@ -19,6 +19,7 @@ export default defineConfig({ items: [ { text: 'JavaScript', link: '/JavaScript/JS基础/作用域&提升&闭包.md' }, { text: 'Typescript', link: '/Typescript/常用工具类.md' }, + { text: 'ReactNative', link: '/ReactNative/RN新架构.md' }, { text: 'Canvas', link: '/Canvas/基础/Canvas组件.md' }, { text: 'CSS', link: '/CSS/超出省略.md' }, { text: 'HTML', link: '/HTML/DOM操作.md' }, diff --git a/docs/Logs/2024.md b/docs/Logs/2024.md index c01e880..bea791a 100644 --- a/docs/Logs/2024.md +++ b/docs/Logs/2024.md @@ -1,5 +1,9 @@ # 更新日志 +- `2024-04-26` - Git项目太大克隆失败 + +- `2024-04-15` - RN新架构 一、React&CodeGen + - `2024-03-31` - line-height、Wake Lock API - `2024-03-30` - Set数据类型 diff --git "a/docs/ReactNative/RN\346\226\260\346\236\266\346\236\204.md" "b/docs/ReactNative/RN\346\226\260\346\236\266\346\236\204.md" new file mode 100644 index 0000000..29c4b71 --- /dev/null +++ "b/docs/ReactNative/RN\346\226\260\346\236\266\346\236\204.md" @@ -0,0 +1,55 @@ +# RN新架构 + +RN是一个跨平台解决方案,允许开发者使用`React`(和`JavaScript`)创建原生移动端应用,其中有四个核心部分: + +- **`React`**:开发者**使用React编写的书面代码**,包括React组件、函数逻辑以及JS代码等 +- **`JavaScript`**:RN框架将React组件和逻辑转换成JavaScript语句,以便运行时环境能够理解和执行 +- **`Bridge`**:JS代码和Native代码之间会通过一组元素进行通信交互。通信通常是异步`JSON`消息,这组元素起到桥梁的作用,因此被称为`Bridge` +- **`Native`**:Native代码指的是在移动设备上运行的**原生代码**,例如`Android`上的**Java**或**Kotlin**代码以及`IOS`上的**Objective-C**或**Swift**代码,Native代码可以访问设备的原生功能,能执行更高性能的任务 + +![react native diagram](https://res.cloudinary.com/formidablelabs/image/upload/f_auto,q_auto/v1675121564/dotcom/uploads-old-diagram-full) + +JS代码和Native代码的环境是隔离的,只能通过`Bridge`组件传输异步的JSON信息,这些信息被发送到Native代码后无法保证一定有响应,是有局限性的,所以RN团队对这四个核心部分逐一改进,组成了新架构 + +## 一、React&CodeGen + +具体来说,第一部分改进了以下几个方面: + +1. **新的React特性**:引入了**并发模式**和**同步事件回调**等新特性,提高了应用的性能和响应性。 +2. **Suspense和Hooks**:`Suspense`优化异步数据的加载,`Hooks`使代码更加简洁和可维护。 +3. **静态类型检查器和CodeGen**:新架构强调了静态类型检查器(如`Flow`或`TypeScript`)的重要性,并引入了一个名为`CodeGen`的工具,用于自动生成JS和本地代码之间的接口文件。 + +![React Native overview with Codegen](https://res.cloudinary.com/formidablelabs/image/upload/f_auto,q_auto/v1675121564/dotcom/uploads-new-1) + +## 二、JSI&JSC + +在旧架构中,`JSC(JavaScriptCore)`引擎被直接用于解释 JavaScript 代码。但这样做的缺点是,通信效率差,JS和Native之间是隔离的, + +新架构中引入了一个名为`JavaScript Interface (JSI)`的新模块,将JS代码与JSC引擎分离,这样做的优点如下: + +1. 易于更新引擎:可以更容易地将 JSC 替换为其他引擎或较新版本的 JSC +2. **`直接JS调用C++的方法`**:这是新架构的核心功能,JSI可以让JS持有对C++主机对象的引用,并调用它们的方法,这意味着JS与Native的通信将更加高效 + +- 易于更新引擎: +- + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/ReactNative/react-native-echarts-pro.md b/docs/ReactNative/react-native-echarts-pro.md deleted file mode 100644 index a8499a3..0000000 --- a/docs/ReactNative/react-native-echarts-pro.md +++ /dev/null @@ -1,167 +0,0 @@ -# react-native-echarts-pro - -## 一、安装 - -查看[官网文档](https://supervons.github.io/react-native-echarts-pro-docs/zh-cn/docs/intro)安装,要注意的是`react-native-webview`需要手动安装,因为echarts-pro代码中需要用到 - -``` -npm i react-native-webview -``` - -## 二、属性 - -具体可见:[参考文档](https://supervons.github.io/react-native-echarts-pro-docs/zh-cn/docs/tutorial-basics/props) - -| 属性名 | 类型 | 默认值 | 必填 | 描述 | -| ------------------------- | ------- | ----------- | ---- | ------------------------------------------------------------ | -| height | Number | 400 | Y | 图表区域高度 | -| width | Number | auto | N | 图表区域宽度 | -| option | Object | null | Y | 图表核心配置项,请参考:[Apache ECharts - options](https://echarts.apache.org/en/option.html#title) | -| backgroundColor | String | transparent | N | 背景颜色 | -| themeName | String | - | N | 内置主题 ,六种可选: `vintage` `dark` `macarons` `infographic` `shine` `roma` | -| webViewSettings | Object | null | N | 自定义 WebView 容器属性 | -| formatterVariable | Object | null | N | 如果 formatter 使用了动态单位变量,使用此属性传入 | -| extension | object | null | N | 动态扩展支持,如词云、水球图等 | -| customMapData | Object | world JSON | N | 自定义地图数据,默认为世界地图 JSON | -| eventActions | Object | null | N | 自定义传入事件 | -| fontFamilies | Array | [] | N | 自定义字体数组 | -| enableParseStringFunction | Boolean | false | N | 开启后,`function` 将以字符串进行传递 | - -## 三、示例 - -> 以下示例都忽略了配置项,详细请参考:[Apache ECharts - options](https://echarts.apache.org/en/option.html#title) - -`height`/`width`/`option`/`backgroundColor` - -```tsx - -``` - -`themeName`/`webViewSettings` - -```tsx - -``` - -`formatterVariable`动态单位,需要和`enableParseStringFunction`一起使用才能生效 - -```tsx -const MyChartComponent = () => { - const option = { - // ... - yAxis: { - type: 'value', - axisLabel: { - formatter: `function (val) { - return val + formatterVariable.unit; - }`, - }, - }, - }; - - return ( - - ); -}; -``` - -`extension`:除了内置图表以外,还支持更多三方图表样式,以下面的水球图为例: - -```tsx -export default function App(): React.JSX.Element { - const liquidOption = { - series: [ - { - type: "liquidFill", - data: [0.6], - color: ["#afb11b"], - itemStyle: { - opacity: 0.6, - }, - emphasis: { - itemStyle: { - opacity: 0.9, - }, - }, - }, - ], - }; - - return ( - - ); -} - - -``` - -`customMapData`自定义地图,数据可以从[geojson](https://geojson.io/)下载,例如[中国](https://github.com/supervons/react-native-echarts-pro/blob/master/src/components/Echarts/map/chinaJson.js)地图 - -```tsx -import ChinaJsonData from "./chinaJson.js"; -export default function Demo2() { - return ( - - ); -} -``` - -`eventActions`自定义图表事件,详细的[事件列表](https://echarts.apache.org/zh/api.html#events) - -```jsx - return ( - { - alert(1) - }, - }} - /> - ); -``` - -`fontFamilies` 自定义字体,参考[文档](https://supervons.github.io/react-native-echarts-pro-docs/zh-cn/docs/tutorial-fontfamily/custom)将字体转换为base64。然后新建js模块导出 - -```tsx -const FangSong = ` -@font-face { - font-family: 'FangSong'; - src: url('base64字体....'); - font-weight: normal; - font-style: normal; - font-display: swap; -} -` - -``` - diff --git a/docs/ReactNative/react-native-worklets-core.md b/docs/ReactNative/react-native-worklets-core.md deleted file mode 100644 index b09ca7c..0000000 --- a/docs/ReactNative/react-native-worklets-core.md +++ /dev/null @@ -1,201 +0,0 @@ -# react-native-worklets-core - -## 安装 - -从 npm 安装库,文档参考[Github官网仓库](https://github.com/margelo/react-native-worklets-core/) - -``` -yarn add react-native-worklets-core -``` - -将 babel 插件添加到您的 `babel.config.js` 中 - -```js -module.exports = { - plugins: [ - ["react-native-worklets-core/plugin"], - // 其他插件... - ], - // 其他配置... -}; - -``` - -重启 Metro,并清除缓存: - -``` -yarn start --reset-cache -``` - -## 修改源码引用 - -`node_modules\react-native-worklets-core\src\index.ts`添加最后一行缺失的导出 - -```ts -import "./NativeWorklets"; -export * from "./types"; -export * from "./hooks/useSharedValue"; -export * from "./hooks/useWorklet"; -export * from "./hooks/useRunInJS"; -``` - -`node_modules\react-native-worklets-core\src\hooks\useWorklet.ts`修改引用路径 - -```ts -import { DependencyList, useMemo } from "react"; -import type { IWorkletContext } from "../../src/types"; -``` - -`node_modules\react-native-worklets-core\lib\commonjs\index.js` 新增 - -```js -var _useRunInJS = require("./hooks/useRunInJS"); -Object.keys(_useRunInJS).forEach(function (key) { - if (key === "default" || key === "__esModule") return; - if (key in exports && exports[key] === _useRunInJS[key]) return; - Object.defineProperty(exports, key, { - enumerable: true, - get: function () { - return _useRunInJS[key]; - } - }); -}); -``` - -`node_modules\react-native-worklets-core\lib\module\index.js` 新增 - -```js -export * from "./hooks/useRunInJS"; -``` - -`node_modules\react-native-worklets-core\lib\typescript\index.d.ts` 新增 - -```ts -export * from "./hooks/useRunInJS"; -``` - -`lib\typescript\hooks\useWorklet.d.ts`修改 - -```ts -import type { IWorkletContext } from "../types"; -``` - -## 使用方法 - -将可能引起阻塞的操作使用`useWorklet`包裹 - -```ts -const runInWorkLet9 = useWorklet('default', () => { - 'worklet'; - let result = 0; - for (let i = 0; i < 1e9; i++) { - result += i; - } -}, []); -``` - -worklet的上下文和js不一样,**js中定义或引入的变量和方法都不能直接调用**,如有需要,就需要使用`useRunInJS`创建一个新方法,如果有依赖可以放在第二个参数中,一旦依赖项发生变化,方法也会更新 - -```ts -const [endTime, setEndTime] = useState(Date.now()); -const setNewEndTime = useRunInJS(() => { - setEndTime(Date.now()); -}, [endTime]); -``` - -## 实例Demo - -```tsx -import { useEffect, useState } from "react"; -import { Alert, Button, Image, StyleSheet, Text, View } from "react-native" -import { useRunInJS, useSharedValue, useWorklet } from "react-native-worklets-core"; - -const App = () => { - const [curTime, setCurTime] = useState(0); // 时间戳 - const runMsg = useSharedValue('等待中'); - - useEffect(() => { - const timer = setInterval(() => { - setCurTime(Math.floor(Date.now())) - }, 500) - return () => { - clearInterval(timer) - } - }, []) - - // js 阻塞方法 - const runInJs = () => { - const start = Date.now(); - let result = 0; - for (let i = 0; i < 1e8; i++) { - result += i; - } - const end = Date.now(); - const msg = `js操作完成,运行时长:${(end - start) / 1000} 秒`; - runMsg.value = msg; - } - - // worklet 阻塞方法 - const runInWorkLet = useWorklet('default', () => { - 'worklet'; - runMsg.value = '执行中,请等待...'; - const start = Date.now(); - let result = 0; - for (let i = 0; i < 1e8; i++) { - result += i; - } - const end = Date.now(); - const msg = `worklet操作完成,运行时长:${(end - start) / 1000} 秒`; - runMsg.value = msg; - }, []); - - const run = (type: 'js' | 'worklet') => { - if (type === 'js') { - runInJs() - } else { - runInWorkLet() - } - } - - return ( - - - useRunInJS/useWorklet - 该Demo用于展示worklet线程与js线程的差异 - 当前使用循环来模拟耗时操作,循环次数越大需要处理的时间越长 - - - 通过 useWorklet 创建线程,在两个线程分别遍历1e8次 - -