From 7d0945a5459dc2292a20bd674a7a4cc402b7b836 Mon Sep 17 00:00:00 2001
From: yujiang <287650464@qq.com>
Date: Tue, 5 Mar 2024 10:24:14 +0800
Subject: [PATCH 1/9] =?UTF-8?q?[Issues:=20#I95SUW]=20=E6=B7=BB=E5=8A=A0rea?=
=?UTF-8?q?ct-lifecycles-compat=E6=93=8D=E4=BD=9C=E6=96=87=E6=A1=A3?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
1224/react-lifecycles-compat.md | 130 ++++++++++++++++++++++++++++++++
1 file changed, 130 insertions(+)
create mode 100644 1224/react-lifecycles-compat.md
diff --git a/1224/react-lifecycles-compat.md b/1224/react-lifecycles-compat.md
new file mode 100644
index 00000000..34a25e4a
--- /dev/null
+++ b/1224/react-lifecycles-compat.md
@@ -0,0 +1,130 @@
+> 模板版本:v0.1.3
+
+
+
react-lifecycles-compat
+
+
+
+
+
+
+
+
+> [!TIP] [Github 地址](https://github.com/reactjs/react-lifecycles-compat)
+
+## 安装与使用
+
+进入到工程目录并输入以下命令:
+
+>[!TIP] # 处替换为 tgz 包的路径
+
+
+
+#### **npm**
+
+```bash
+npm install react-lifecycles-compat@3.0.4
+```
+
+#### **yarn**
+
+```bash
+yarn add react-lifecycles-compat@file@3.0.4
+```
+
+
+
+下面的代码展示了这个库的基本使用场景:
+
+```js
+import React from 'react';
+import {
+ Text,
+ View,
+ Button
+} from 'react-native';
+import { polyfill } from 'react-lifecycles-compat';
+import { State } from 'react-native-gesture-handler';
+class ShowComponent extends React.Component {
+ render() {
+ return (
+
+ 新组件
+
+ )
+ }
+}
+class ExampleComponent extends React.Component {
+ state = {
+ Text1: '未执行',
+ count1: 0,
+ Text2: '未执行',
+ visible: false
+ };
+ static getDerivedStateFromProps = (nextProps, prevState) => {
+ // Normally this method would only work for React 16.3 and newer,
+ // But the polyfill will make it work for older versions also!
+ return { Text1: '已执行', count1: prevState.count1 + 1 }
+ }
+
+ getSnapshotBeforeUpdate(prevProps, prevState) {
+ // Normally this method would only work for React 16.3 and newer,
+ // But the polyfill will make it work for older versions also!
+ return true
+ }
+ componentDidUpdate(prevProps, prevState, snapshot) {
+ if (snapshot) {
+ if (this.state.Text2 !== '已执行') {
+ this.setState({
+ Text2: '已执行'
+ })
+ }
+
+ }
+ }
+ // render() and other methods ...
+ handleClick = () => {
+ this.setState({ visible: true })
+ }
+ render() {
+ const { visible, Text1, Text2, count1 } = this.state
+ return (
+
+ {visible ? : {visible}}
+ getDerivedStateFromProps生命周期会在React初始化挂载和后续更新时调用render之前调用,返回一个对象来更新state,或者返回null就不更新任何内容
+ getSnapshotBeforeUpdate生命周期会在React更新DOM之前时直接调用,使你的组件能够在DOM发生更改之前捕获一些信息
+
+ 生命周期getDerivedStateFromProps{this.state.Text1}+{this.state.count1}
+ 生命周期getSnapshotBeforeUpdate{this.state.Text2}
+
+ )
+ }
+
+}
+
+// Polyfill your component so the new lifecycles will work with older versions of React:
+polyfill(ExampleComponent);
+
+export default ExampleComponent;
+```
+
+### 兼容性
+
+在以下版本验证通过
+
+1. RNOH:0.72.13; SDK:HarmonyOS NEXT Developer Preview1; IDE:DevEco Studio 4.1.3.500; ROM:204.1.0.59;
+
+| Name | Description | Required | Platform | HarmonyOS Support |
+| ------------------------ | -------------------------------------- | -------- | -------- | ----------------- |
+| getDerivedStateFromProps | Initialize the mount. | NO | Android | YES |
+| getSnapshotBeforeUpdate | Call directly before updating the DOM. | NO | Android | YES |
+
+## 遗留问题
+
+## 其他
+
+Note that in order for the polyfill to work, none of the following lifecycles can be defined by your component: `componentWillMount`, `componentWillReceiveProps`, or `componentWillUpdate`.
+
+Note also that if your component contains `getSnapshotBeforeUpdate`, `componentDidUpdate` must be defined as well.
+
+An error will be thrown if any of the above conditions are not met.
--
Gitee
From ac0c8be2fd56446c120e2aaf339af3cb7d908942 Mon Sep 17 00:00:00 2001
From: yujiang <287650464@qq.com>
Date: Tue, 5 Mar 2024 10:48:21 +0800
Subject: [PATCH 2/9] =?UTF-8?q?[Issues:=20#I95SUW]=20=E6=B7=BB=E5=8A=A0rea?=
=?UTF-8?q?ct-lifecycles-compat=E6=93=8D=E4=BD=9C=E6=96=87=E6=A1=A3?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
1224/react-lifecycles-compat.md | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/1224/react-lifecycles-compat.md b/1224/react-lifecycles-compat.md
index 34a25e4a..513148ff 100644
--- a/1224/react-lifecycles-compat.md
+++ b/1224/react-lifecycles-compat.md
@@ -29,7 +29,7 @@ npm install react-lifecycles-compat@3.0.4
#### **yarn**
```bash
-yarn add react-lifecycles-compat@file@3.0.4
+yarn add react-lifecycles-compat@3.0.4
```
@@ -123,8 +123,6 @@ export default ExampleComponent;
## 其他
-Note that in order for the polyfill to work, none of the following lifecycles can be defined by your component: `componentWillMount`, `componentWillReceiveProps`, or `componentWillUpdate`.
+请注意,为了使polyfill工作,您的组件不能定义以下生命周期:componentWillMount,componentWillReceiveProps,componentWillUpdate.
-Note also that if your component contains `getSnapshotBeforeUpdate`, `componentDidUpdate` must be defined as well.
-
-An error will be thrown if any of the above conditions are not met.
+还要注意,如果您的组件包含getSnapshotBeforeUpdate,那么也必须定义componentDidUpdate,如果不满足上述任何条件,将抛出错误.
--
Gitee
From 52fc80cc5db63a68f4fda8e622d4766f227d03d1 Mon Sep 17 00:00:00 2001
From: yujiang <287650464@qq.com>
Date: Tue, 5 Mar 2024 11:14:50 +0800
Subject: [PATCH 3/9] =?UTF-8?q?[Issues:=20#I95SUW]=20=E6=B7=BB=E5=8A=A0rea?=
=?UTF-8?q?ct-lifecycles-compat=E6=93=8D=E4=BD=9C=E6=96=87=E6=A1=A3?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
1224/react-lifecycles-compat.md | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/1224/react-lifecycles-compat.md b/1224/react-lifecycles-compat.md
index 513148ff..aefa952d 100644
--- a/1224/react-lifecycles-compat.md
+++ b/1224/react-lifecycles-compat.md
@@ -123,6 +123,8 @@ export default ExampleComponent;
## 其他
-请注意,为了使polyfill工作,您的组件不能定义以下生命周期:componentWillMount,componentWillReceiveProps,componentWillUpdate.
+以下事项于原库保持一致需注意遵循:
-还要注意,如果您的组件包含getSnapshotBeforeUpdate,那么也必须定义componentDidUpdate,如果不满足上述任何条件,将抛出错误.
+为了使polyfill工作,您的组件不能定义以下生命周期:componentWillMount,componentWillReceiveProps,componentWillUpdate.
+
+如果您的组件包含getSnapshotBeforeUpdate,那么也必须定义componentDidUpdate,如果不满足上述任何条件,将抛出错误.
--
Gitee
From bccb00343ec1bb0598228700a982847b5820d79e Mon Sep 17 00:00:00 2001
From: yujiang <287650464@qq.com>
Date: Tue, 5 Mar 2024 11:25:12 +0800
Subject: [PATCH 4/9] =?UTF-8?q?[Issues:=20#I95SUW]=20=E6=B7=BB=E5=8A=A0rea?=
=?UTF-8?q?ct-lifecycles-compat=E6=93=8D=E4=BD=9C=E6=96=87=E6=A1=A3?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
1224/react-lifecycles-compat.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/1224/react-lifecycles-compat.md b/1224/react-lifecycles-compat.md
index aefa952d..0ee89e30 100644
--- a/1224/react-lifecycles-compat.md
+++ b/1224/react-lifecycles-compat.md
@@ -123,7 +123,7 @@ export default ExampleComponent;
## 其他
-以下事项于原库保持一致需注意遵循:
+以下事项与原库保持一致需注意遵循:
为了使polyfill工作,您的组件不能定义以下生命周期:componentWillMount,componentWillReceiveProps,componentWillUpdate.
--
Gitee
From 54cbbaac782d3924d57782e3461e7c07490006b3 Mon Sep 17 00:00:00 2001
From: yujiang <287650464@qq.com>
Date: Wed, 6 Mar 2024 11:56:24 +0800
Subject: [PATCH 5/9] =?UTF-8?q?[Issues:=20#I95SUW]=20=E6=B7=BB=E5=8A=A0rea?=
=?UTF-8?q?ct-lifecycles-compat=E6=93=8D=E4=BD=9C=E6=96=87=E6=A1=A3?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
1224/axios.md | 149 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 149 insertions(+)
create mode 100644 1224/axios.md
diff --git a/1224/axios.md b/1224/axios.md
new file mode 100644
index 00000000..8dadf1ae
--- /dev/null
+++ b/1224/axios.md
@@ -0,0 +1,149 @@
+> 模板版本:v0.1.3
+
+
+
axios
+
+
+
+
+
+
+> [!tip] [Github 地址](https://github.com/axios/axios)
+
+## 安装与使用
+
+#### **npm**
+
+```bash
+npm install axios@0.28.0
+```
+
+#### **bower**
+
+```bash
+bower install axios@0.28.0
+```
+
+#### **yarn**
+
+```bash
+yarn add axios@0.28.0
+```
+
+Once the package is installed, you can import the library using `import` or `require` approach:
+
+```js
+import axios, {isCancel, AxiosError} from 'axios';
+```
+
+You can also use the default export, since the named export is just a re-export from the Axios factory:
+
+```js
+import axios from 'axios';
+
+console.log(axios.isCancel('something'));
+```
+
+
+下面的代码展示了这个库的基本使用场景:
+
+>[!WARNING] 使用时 import 的库名不变。
+
+```js
+import axios from 'axios';
+//const axios = require('axios'); // legacy way
+
+// Make a request for a user with a given ID
+axios.get('/user?ID=12345')
+ .then(function (response) {
+ // handle success
+ console.log(response);
+ })
+ .catch(function (error) {
+ // handle error
+ console.log(error);
+ })
+ .finally(function () {
+ // always executed
+ });
+
+// Optionally the request above could also be done as
+axios.get('/user', {
+ params: {
+ ID: 12345
+ }
+ })
+ .then(function (response) {
+ console.log(response);
+ })
+ .catch(function (error) {
+ console.log(error);
+ })
+ .finally(function () {
+ // always executed
+ });
+
+// Want to use async/await? Add the `async` keyword to your outer function/method.
+async function getUser() {
+ try {
+ const response = await axios.get('/user?ID=12345');
+ console.log(response);
+ } catch (error) {
+ console.error(error);
+ }
+}
+```
+
+## 约束与限制
+
+## 兼容性
+
+本文档内容基于以下版本验证通过:
+
+1. RNOH:0.72.13; SDK:HarmonyOS NEXT Developer Preview1; IDE:DevEco Studio 4.1.3.500; ROM:2.0.0.59;
+
+## API
+
+> [!tip] "Platform"列表示该属性在原三方库上支持的平台。
+
+> [!tip] "HarmonyOS Support"列为 yes 表示 HarmonyOS 平台支持该属性;no 则表示不支持;partially 表示部分支持。使用方法跨平台一致,效果对标 iOS 或 Android 的效果。
+
+| Name | Description | Type | Required | HarmonyOS Support |
+| :------------ | ----------- | :--: | :------: | :----------------: |
+| axios.request(config) | 别名发送request请求 | function | / | yes |
+| axios.get(url[, config]) | 别名发送get请求 | function | / | yes |
+| axios.delete(url[, config]) | 别名发送delete请求 | function | / | yes |
+| axios.head(url[, config]) | 别名发送head请求 | function | / | yes |
+| axios.options(url[, config]) | 别名发送options请求 | function | / | yes |
+| axios.post(url[, data[, config]]) | 别名发送post请求 | function | / | yes |
+| axios.put(url[, data[, config]]) | 别名发送put请求 | function | / | yes |
+| axios.patch(url[, data[, config]]) | 别名发送patch请求 | function | / | yes |
+| axios#request(config) | 实例发送request请求 | function | / | yes |
+| axios#get(url[, config]) | 实例发送get请求 | function | / | yes |
+| axios#delete(url[, config]) | 实例发送delete请求 | function | / | yes |
+| axios#head(url[, config]) | 实例发送head请求 | function | / | yes |
+| axios#options(url[, config]) | 实例发送options请求 | function | / | yes |
+| axios#post(url[, data[, config]]) | 实例发送post请求 | function | / | yes |
+| axios#put(url[, data[, config]]) | 实例发送put请求 | function | / | yes |
+| axios#patch(url[, data[, config]]) | 实例发送patch请求 | function | / | yes |
+| url | 配置中请求的地址 | function | / | yes |
+| method | 配置中请求时使用的方法 | function | / | yes |
+| baseURL | 配置中自动加在url地址前 | function | / | yes |
+| headers | 配置中自定义请求头 | function | / | yes |
+| params | 配置中请求一起发送时的参数 | function | / | yes |
+| data | 配置中请求体发送的数据 | function | / | yes |
+| timeout | 配置中请求超时的毫秒数 | function | / | yes |
+| proxy | 配置中设置代理 | function | / | yes |
+| Response Schema | 响应类型 | function | / | yes |
+| Config Defaults | 默认配置 | function | / | yes |
+| requestInterceptors | 请求拦截器 | function | / | yes |
+| responseInterceptors | 响应拦截器 | function | / | yes |
+| Handling Errors | 错误处理 | function | / | yes |
+| AbortController | 中止控制器 | function | / | yes |
+| CancelToken | 取消令牌 | function | / | yes |
+
+## 其他
+
+## 开源协议
+
+本项目基于 [The MIT License (MIT)](https://github.com/Kureev/react-native-blur/blob/master/LICENSE) ,请自由地享受和参与开源。
--
Gitee
From cdb0bc4ad97c967bc7f90fa574d69a88b495b840 Mon Sep 17 00:00:00 2001
From: yujiang <287650464@qq.com>
Date: Wed, 6 Mar 2024 12:00:37 +0800
Subject: [PATCH 6/9] =?UTF-8?q?[Issues:=20#I95SUW]=20=E6=B7=BB=E5=8A=A0rea?=
=?UTF-8?q?ct-lifecycles-compat=E6=93=8D=E4=BD=9C=E6=96=87=E6=A1=A3?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
1224/axios.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/1224/axios.md b/1224/axios.md
index 8dadf1ae..0e765853 100644
--- a/1224/axios.md
+++ b/1224/axios.md
@@ -8,7 +8,7 @@
-> [!tip] [Github 地址](https://github.com/axios/axios)
+> [!TIP] [Github 地址](https://github.com/axios/axios)
## 安装与使用
--
Gitee
From 1dd30421e09dcd6a5df46742d9bf5f607ea605c1 Mon Sep 17 00:00:00 2001
From: yujiang <287650464@qq.com>
Date: Wed, 6 Mar 2024 12:04:53 +0800
Subject: [PATCH 7/9] =?UTF-8?q?[Issues:=20#I95SUW]=20=E6=B7=BB=E5=8A=A0rea?=
=?UTF-8?q?ct-lifecycles-compat=E6=93=8D=E4=BD=9C=E6=96=87=E6=A1=A3?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
1224/axios.md | 2 ++
1 file changed, 2 insertions(+)
diff --git a/1224/axios.md b/1224/axios.md
index 0e765853..fae2d4d8 100644
--- a/1224/axios.md
+++ b/1224/axios.md
@@ -8,6 +8,8 @@
+
+
> [!TIP] [Github 地址](https://github.com/axios/axios)
## 安装与使用
--
Gitee
From cab45f720141b222a309a98e5069915da9acf855 Mon Sep 17 00:00:00 2001
From: yujiang <287650464@qq.com>
Date: Wed, 6 Mar 2024 12:05:25 +0800
Subject: [PATCH 8/9] =?UTF-8?q?[Issues:=20#I95SUW]=20=E6=B7=BB=E5=8A=A0rea?=
=?UTF-8?q?ct-lifecycles-compat=E6=93=8D=E4=BD=9C=E6=96=87=E6=A1=A3?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
1224/axios.md | 151 --------------------------------------------------
1 file changed, 151 deletions(-)
delete mode 100644 1224/axios.md
diff --git a/1224/axios.md b/1224/axios.md
deleted file mode 100644
index fae2d4d8..00000000
--- a/1224/axios.md
+++ /dev/null
@@ -1,151 +0,0 @@
-> 模板版本:v0.1.3
-
-
-
axios
-
-
-
-
-
-
-
-
-> [!TIP] [Github 地址](https://github.com/axios/axios)
-
-## 安装与使用
-
-#### **npm**
-
-```bash
-npm install axios@0.28.0
-```
-
-#### **bower**
-
-```bash
-bower install axios@0.28.0
-```
-
-#### **yarn**
-
-```bash
-yarn add axios@0.28.0
-```
-
-Once the package is installed, you can import the library using `import` or `require` approach:
-
-```js
-import axios, {isCancel, AxiosError} from 'axios';
-```
-
-You can also use the default export, since the named export is just a re-export from the Axios factory:
-
-```js
-import axios from 'axios';
-
-console.log(axios.isCancel('something'));
-```
-
-
-下面的代码展示了这个库的基本使用场景:
-
->[!WARNING] 使用时 import 的库名不变。
-
-```js
-import axios from 'axios';
-//const axios = require('axios'); // legacy way
-
-// Make a request for a user with a given ID
-axios.get('/user?ID=12345')
- .then(function (response) {
- // handle success
- console.log(response);
- })
- .catch(function (error) {
- // handle error
- console.log(error);
- })
- .finally(function () {
- // always executed
- });
-
-// Optionally the request above could also be done as
-axios.get('/user', {
- params: {
- ID: 12345
- }
- })
- .then(function (response) {
- console.log(response);
- })
- .catch(function (error) {
- console.log(error);
- })
- .finally(function () {
- // always executed
- });
-
-// Want to use async/await? Add the `async` keyword to your outer function/method.
-async function getUser() {
- try {
- const response = await axios.get('/user?ID=12345');
- console.log(response);
- } catch (error) {
- console.error(error);
- }
-}
-```
-
-## 约束与限制
-
-## 兼容性
-
-本文档内容基于以下版本验证通过:
-
-1. RNOH:0.72.13; SDK:HarmonyOS NEXT Developer Preview1; IDE:DevEco Studio 4.1.3.500; ROM:2.0.0.59;
-
-## API
-
-> [!tip] "Platform"列表示该属性在原三方库上支持的平台。
-
-> [!tip] "HarmonyOS Support"列为 yes 表示 HarmonyOS 平台支持该属性;no 则表示不支持;partially 表示部分支持。使用方法跨平台一致,效果对标 iOS 或 Android 的效果。
-
-| Name | Description | Type | Required | HarmonyOS Support |
-| :------------ | ----------- | :--: | :------: | :----------------: |
-| axios.request(config) | 别名发送request请求 | function | / | yes |
-| axios.get(url[, config]) | 别名发送get请求 | function | / | yes |
-| axios.delete(url[, config]) | 别名发送delete请求 | function | / | yes |
-| axios.head(url[, config]) | 别名发送head请求 | function | / | yes |
-| axios.options(url[, config]) | 别名发送options请求 | function | / | yes |
-| axios.post(url[, data[, config]]) | 别名发送post请求 | function | / | yes |
-| axios.put(url[, data[, config]]) | 别名发送put请求 | function | / | yes |
-| axios.patch(url[, data[, config]]) | 别名发送patch请求 | function | / | yes |
-| axios#request(config) | 实例发送request请求 | function | / | yes |
-| axios#get(url[, config]) | 实例发送get请求 | function | / | yes |
-| axios#delete(url[, config]) | 实例发送delete请求 | function | / | yes |
-| axios#head(url[, config]) | 实例发送head请求 | function | / | yes |
-| axios#options(url[, config]) | 实例发送options请求 | function | / | yes |
-| axios#post(url[, data[, config]]) | 实例发送post请求 | function | / | yes |
-| axios#put(url[, data[, config]]) | 实例发送put请求 | function | / | yes |
-| axios#patch(url[, data[, config]]) | 实例发送patch请求 | function | / | yes |
-| url | 配置中请求的地址 | function | / | yes |
-| method | 配置中请求时使用的方法 | function | / | yes |
-| baseURL | 配置中自动加在url地址前 | function | / | yes |
-| headers | 配置中自定义请求头 | function | / | yes |
-| params | 配置中请求一起发送时的参数 | function | / | yes |
-| data | 配置中请求体发送的数据 | function | / | yes |
-| timeout | 配置中请求超时的毫秒数 | function | / | yes |
-| proxy | 配置中设置代理 | function | / | yes |
-| Response Schema | 响应类型 | function | / | yes |
-| Config Defaults | 默认配置 | function | / | yes |
-| requestInterceptors | 请求拦截器 | function | / | yes |
-| responseInterceptors | 响应拦截器 | function | / | yes |
-| Handling Errors | 错误处理 | function | / | yes |
-| AbortController | 中止控制器 | function | / | yes |
-| CancelToken | 取消令牌 | function | / | yes |
-
-## 其他
-
-## 开源协议
-
-本项目基于 [The MIT License (MIT)](https://github.com/Kureev/react-native-blur/blob/master/LICENSE) ,请自由地享受和参与开源。
--
Gitee
From d712b1c8556f7d159bb7bcc84d9cd1f061f20d55 Mon Sep 17 00:00:00 2001
From: yujiang <287650464@qq.com>
Date: Wed, 20 Mar 2024 10:03:26 +0800
Subject: [PATCH 9/9] =?UTF-8?q?[Issues:=20#I99Y71]=20=E6=B7=BB=E5=8A=A0imm?=
=?UTF-8?q?er=E6=93=8D=E4=BD=9C=E6=96=87=E6=A1=A3?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
1224/Immer.md | 736 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 736 insertions(+)
create mode 100644 1224/Immer.md
diff --git a/1224/Immer.md b/1224/Immer.md
new file mode 100644
index 00000000..68a50b08
--- /dev/null
+++ b/1224/Immer.md
@@ -0,0 +1,736 @@
+模板版本:v0.1.3
+
+
+
immer
+
+
+
+
+
+
+
+
+
+> [!TIP] [Github 地址](https://github.com/immerjs/immer)
+
+## 安装与使用
+
+进入到工程目录并输入以下命令:
+
+>[!TIP] # 处替换为 tgz 包的路径
+
+
+
+#### **npm**
+
+```bash
+npm immer@10.0.3
+```
+
+#### **yarn**
+
+```bash
+yarn add immer@10.0.3
+```
+
+
+
+下面的代码展示了这个库的基本使用场景:
+
+```js
+import React, {useState, useEffect} from 'react';
+import {View, Text, Button, StyleSheet, ScrollView} from 'react-native';
+import {
+ createDraft,
+ finishDraft,
+ current,
+ produce,
+ original,
+ isDraft,
+ enablePatches,
+ produceWithPatches,
+ enableMapSet,
+ freeze,
+ nothing,
+ setAutoFreeze,
+ isDraftable,
+ immerable,
+ Immutable,
+ castImmutable,
+ castDraft,
+ applyPatches,
+} from 'immer';
+
+// 初始状态
+const initialState = {
+ count: 0,
+ text: 'Hello from Immer!',
+};
+enablePatches();
+// 启用enablePatches插件
+enableMapSet();
+// 启用enableMapSet插件
+class ShowComponent extends React.Component {
+ state = {
+ mapData: new Map(),
+ setData: new Set(),
+ };
+
+ updateData = () => {
+ this.setState(
+ produce(draft => {
+ draft.mapData.set('key', 'value');
+ draft.setData.add('new item');
+ }),
+ );
+ };
+
+ render() {
+ return (
+
+
+ Map Data: {Array.from(this.state.mapData)}
+ Set Data: {Array.from(this.state.setData)}
+
+ );
+ }
+}
+const MyComponent = () => {
+ let [states, setStates] = useState(false);
+ const [originals, setOriginals] = useState({users: [{name: 'zhansan'}]});
+ let [res, setRes] = useState('');
+ let [currentText, setCurrent] = useState('');
+ // ----------------------------------------------------
+ const [count, setCount] = useState({age: 0});
+ let [baseState, setBaseState] = useState([
+ {
+ title: '标题1',
+ done: true,
+ },
+ ]);
+ const [text, setText] = useState('Hello');
+ let [result, setResult] = useState({});
+ let [patches, setPatches] = useState({});
+ let [inversePatches, setInversePatches] = useState({});
+ const incrementCount = () => {
+ if (count.age < 3) {
+ setCount(
+ produce(count, draft => {
+ draft.age += 1;
+ }),
+ );
+ } else {
+ setCount(
+ produce(count, draft => {
+ draft.age = 0;
+ }),
+ );
+ }
+ };
+ const decrement = () => {
+ if (count.age > 0) {
+ setCount(
+ produce(count, draft => {
+ draft.age -= 1;
+ }),
+ );
+ } else {
+ setCount(
+ produce(count, draft => {
+ draft.age = 3;
+ }),
+ );
+ }
+ };
+ const onAdd = () => {
+ if (baseState.length < 3) {
+ return setBaseState(
+ produce(baseState, draftState => {
+ draftState.push({title: '新增', done: false});
+ }),
+ );
+ }
+ };
+ const onDelete = (e: number) => {
+ return setBaseState(
+ produce(draft => {
+ draft.splice(e, 1);
+ }),
+ );
+ };
+ const onChange = (item: object, e: number) => {
+ const res = produce(baseState, draftState => {
+ draftState[e].done = !draftState[e].done;
+ draftState[e].title = '更改后数据';
+ setStates((states = isDraft(draftState)));
+ });
+ setBaseState(res);
+ };
+ // ----------------------------------------------------
+ const [state, setState] = useState(initialState);
+ // 使用createDraft来创建一个草稿副本
+ const increment = () => {
+ const draft = createDraft(state);
+ draft.count += 1; // 修改草稿副本
+ // setCurrent(current(draft.count))
+ const nextState = finishDraft(draft); // 获取修改后的不可变状态
+ setState(nextState); // 更新React状态
+ };
+
+ const changeText = () => {
+ const draft = createDraft(state);
+ draft.text = 'Text updated!'; // 修改草稿副本
+ const nextState = current(draft); // 获取当前修改后的状态(与finishDraft效果相同)
+ setState(nextState); // 更新React状态
+ };
+ const clickOriginal = () => {
+ const a = setOriginals(
+ produce(originals, draft => {
+ draft.users[0].name = '4444';
+ setCurrent(current(draft).users[0].name);
+ console.log('Original state:', original(draft)?.users[0].name); // 输出原始状态
+ setRes(original(draft).users[0].name);
+ }),
+ );
+ };
+ const handleClick = () => {
+ const [result, patches, inversePatches] = produceWithPatches(
+ text,
+ draft => (draft += ' World'),
+ );
+ setResult(result);
+ setPatches(patches);
+ setInversePatches(inversePatches);
+ console.log('result:', result);
+ console.log('Patches:', patches);
+ console.log('Inverse Patches:', inversePatches);
+
+ setText(result);
+ };
+ // ---------------------------------------------------------
+ const [stateLeft, setStateLeft] = useState([
+ {count: 0},
+ {age: 17, name: 'zhansan'},
+ ]);
+ const [stateRight, setStateRight] = useState([
+ {count: 0},
+ {age: 17, name: 'zhansan'},
+ ]);
+ const [stateRes, setStateRes] = useState({count: 0});
+ const [stateNothing, setStateNothing] = useState({
+ name: 'John',
+ age: 30,
+ isStudent: false,
+ });
+ const [isDraftableList, setIsDraftableList] = useState({
+ one: false,
+ two: false,
+ three: false,
+ });
+ class MyComponent extends React.Component {
+ constructor(props) {
+ super(props);
+
+ // 设置immerable标志
+ this[immerable] = true;
+
+ this.state = {
+ data: {
+ count: 0,
+ text: 'Hello Immer!',
+ immerable: true,
+ },
+ };
+ }
+
+ incrementCount = () => {
+ this.setState(
+ produce(draft => {
+ draft.data.count += 1;
+ draft.data.text = 'hahhaha';
+ }),
+ );
+ };
+
+ render() {
+ return (
+
+ Count: {this.state.data.count}
+ text: {this.state.data.text}
+
+
+ );
+ }
+ }
+ const [counter, setCounter] = useState>(0);
+ // 在组件挂载时设置 immer 的自动冻结行为
+ useEffect(() => {
+ // 启用自动冻结
+ setAutoFreeze(true);
+
+ // 清理函数(可选),在这里我们不需要做任何清理工作
+ return () => {
+ // 如果需要,可以在这里禁用自动冻结
+ setAutoFreeze(false);
+ };
+ }, []); // 空依赖数组确保此 effect 只运行一次
+ // 使用 immer 的 freeze 函数来冻结状态对象
+ freeze(stateLeft, true);
+ freeze(stateRight, false);
+ // 尝试修改冻结的对象将会失败,并且不会触发组件的重新渲染
+ const tryToModifyFrozenStateLeft = () => {
+ try {
+ setStateRight(
+ produce(pradft => {
+ pradft[0].age = 20;
+ pradft[0].name = 'Lisi';
+ }),
+ );
+ } catch (error) {
+ console.error('Error modifying frozen state:', error);
+ }
+ };
+ const tryToModifyFrozenStateRight = () => {
+ try {
+ setStateRight(
+ produce(pradft => {
+ pradft[1].age = 20;
+ pradft[1].name = 'Lisi';
+ }),
+ );
+ } catch (error) {
+ console.error('Error modifying frozen state:', error);
+ }
+ };
+ const incrementCountLeft = () => {
+ // 使用 setState 来安全地更新状态
+ // setState(prevState => ({state[0].count: prevState[0].count + 1}));
+ setStateLeft(
+ produce(stateLeft, prevState => {
+ prevState[0].count += 1;
+ }),
+ );
+ };
+ const incrementCountRight = () => {
+ // 使用 setState 来安全地更新状态
+ setStateRight(
+ produce(stateRight, prevState => {
+ prevState[0].count += 1;
+ }),
+ );
+ };
+ const ClickincrementCount = () => {
+ // 使用 immer 的 produce 函数来安全地更新状态
+ const nextState = produce(stateRes, draft => {
+ draft.count += 1;
+ });
+ // 由于启用了自动冻结,nextState 现在是一个不可变对象
+ try {
+ // 尝试修改 nextState 将会失败,因为它已经被冻结了
+ nextState.count = 100; // 这会抛出错误,因为 nextState 是不可变的
+ } catch (error) {
+ console.error('Error modifying frozen state:', error);
+ }
+
+ setStateRes(nextState);
+ };
+ const removeProperty = () => {
+ const nextStateNothing = produce(stateNothing, draft => {
+ draft.name = 'wangwu';
+ // 使用 nothing 来删除 age 属性
+ delete draft.age; // 传统的删除方法
+ // 或者使用 immer 的 nothing 来达到相同的效果
+ // draft.isStudent = nothing; // 这将删除 isStudent 属性
+ });
+ setStateNothing(nextStateNothing);
+ console.log('stateNothing:', stateNothing);
+ console.log('nextStateNothing:', typeof nextStateNothing.isStudent);
+ };
+ /* useEffect(() => {
+ console.log('Current state:', stateLeft);
+ }, [stateLeft]); */
+ const clickNothing = () => {
+ const nextStateNothing = produce(stateNothing, draft => {
+ draft.name = 'wangwu';
+ // 使用 nothing 来删除 age 属性
+ // 或者使用 immer 的 nothing 来达到相同的效果
+ draft.isStudent = nothing; // 这将删除 isStudent 属性
+ });
+ setStateNothing(nextStateNothing);
+ console.log('stateNothing:', stateNothing);
+ console.log('nextStateNothing:', typeof nextStateNothing.isStudent);
+ };
+ const checkDraftability = () => {
+ const arr = {
+ one: isDraftable(stateRes),
+ two: isDraftable('Hello, World!'),
+ three: isDraftable(42),
+ };
+ setIsDraftableList(arr);
+ console.log('Is state draftable?', isDraftable(stateRes)); // 应该输出 true
+ console.log('Is string draftable?', isDraftable('Hello, World!')); // 应该输出 false
+ console.log('Is number draftable?', isDraftable(42)); // 应该输出 false
+ // ... 可以检查其他类型的值
+ };
+ const incrementCounter = () => {
+ setCounter(produce(counter, draftCounter => (draftCounter += 10)));
+ };
+ // ------------------------------分割线--------------------------------------------------------------------
+ const [data, setData] = useState({name: 'John', age: 30});
+ const [produceStatus, setProduceStatus] = useState(false);
+ const [castDraftState, setCastDraftState] = useState({
+ count: 0,
+ });
+ const updateData = () => {
+ let newData = {};
+ if (!produceStatus) {
+ newData = produce(data, draft => {
+ draft.age += 1;
+ });
+ } else {
+ newData = castImmutable(data, draft => {
+ draft.age += 1;
+ });
+ }
+
+ setData(newData);
+ console.log('newData:', newData);
+ };
+ const Clickfn = () => {
+ setProduceStatus(!produceStatus);
+ };
+ const AddFn = () => {
+ // 使用immer的produce函数来创建一个新的状态副本
+ const newState = produce(castDraftState, draftState => {
+ // 在新状态副本中增加count的值
+ draftState.count += 1;
+ });
+
+ // 使用castDraft函数确保新状态与原始状态不共享内存
+ const nextState = castDraft(newState);
+ // 更新状态
+ setCastDraftState(nextState);
+ };
+ // ---------------分割--start-----------
+ let originalRes = {
+ name: '初始数据1',
+ age: 18,
+ };
+ let fork = originalRes;
+ // 用户在向导中所作的所有更改
+ let changes = [];
+ // 与向导中所做的所有更改相反
+ let inverseChanges = [];
+ let [obj1, setObj1] = useState({});
+ let [obj2, setObj2] = useState({});
+ const ClickChange = () => {
+ fork = produce(
+ fork,
+ draft => {
+ draft.age = 20;
+ },
+ // 产生的第三个参数是一个回调,patches 将从这里产生
+ (patches, inversePatches) => {
+ changes.push(...patches);
+ inverseChanges.push(...inversePatches);
+ },
+ );
+ // 同时,我们的原始状态被替换,例如
+ // 从服务器收到了一些更改
+ originalRes = produce(originalRes, draft => {
+ draft.name = '更改后数据';
+ });
+ };
+ const fn1 = () => {
+ // 当向导完成(成功)后,我们可以将 fork 中的更改重播到新的状态!
+ let originalRes2 = applyPatches(originalRes, changes);
+ setObj1(originalRes2);
+ };
+ const fn2 = () => {
+ // state 现在包含来自两个代码路径的更改!
+ // 最后,即使在完成向导之后,用户也可能会改变主意并撤消他的更改......
+ let originalRes3 = applyPatches(originalRes, inverseChanges);
+ setObj2(originalRes3);
+ };
+
+ // ----------------分割 end-------------
+ return (
+
+
+ Immer
+ {/* 验证---produce---api */}
+
+ 验证-produce-期望值不可变数据可以更改
+
+
+ Count: {count.age}
+
+
+
+
+ {baseState.map((item, index) => (
+
+
+ 标题:{item.title}
+ 状态:{item.done ? 'true' : 'false'}
+ isDraft状态:{`${states}`}
+
+
+
+
+ ))}
+
+
+ {/* --------验证----createDraft--&--finishDraft---------------- */}
+
+ 验证createDraft--&--finishDraft
+ Count: {state.count}
+ Text: {state.text}
+
+
+
+ {/* -----------------验证--original-------current--------------- */}
+
+
+ 验证original--current--期望值验证original:获取修改后的原始状态
+
+ 初始数据:{JSON.stringify(originals)}
+ original:{res}
+ res:{originals.users[0].name}
+ current: {currentText}
+
+
+ {/* ------enablePatches-----produceWithPatches------------------ */}
+
+ 验证enablePatches--produceWithPatches
+ {text}
+ result:{JSON.stringify(result)}
+ patches:{JSON.stringify(patches)}
+ inversePatches:{JSON.stringify(inversePatches)}
+
+
+ {/* ----------验证--enableMapSet------------------------------- */}
+
+ 验证enableMapSet
+ 123
+
+ {/* ------------------------------------- */}
+ {/* -----------------验证--freeze----------------------- */}
+
+ 验证freeze
+
+
+
+ freez开
+
+ Count: {stateLeft[0].count}
+ age: {stateLeft[1].age}
+ name: {stateLeft[1].name}
+
+
+
+
+
+
+ freez关
+
+ Count: {stateRight[0].count}
+ age: {stateRight[1].age}
+ name: {stateRight[1].name}
+
+
+
+
+
+
+ {/* --------------验证--setAutoFreeze------------------- */}
+
+ ---验证setAutoFreeze----
+ setAutoFreeze为自动冻结,默认为true
+ Current Count: {stateRes.count}
+
+
+ {/* --------------验证---nothing------------------------ */}
+
+ 验证nothing
+ Name: {stateNothing.name}
+ {stateNothing.age !== undefined ? (
+ Age: {stateNothing.age}
+ ) : null}
+ {typeof stateNothing.isStudent == 'boolean' ? (
+ Is Student: {stateNothing.isStudent ? 'Yes' : 'No'}
+ ) : null}
+
+
+ 期望age属性删除
+
+
+
+ 期望is student属性删除
+
+
+
+
+ {/* -----------验证----isDraftable---------------------- */}
+
+ 验证isDraftable
+
+ state:{isDraftableList.one ? 'true' : 'false'}----期望值为true
+
+
+ Hello, World:{isDraftableList.two ? 'true' : 'false'}----期望值false
+
+
+ 42:{isDraftableList.three ? 'true' : 'false'}----期望值false
+
+
+
+ {/* -----------验证---immerable-------------------- */}
+
+ 验证---immerable,期望可以改变值
+
+
+ {/* ----------------验证---Immutable----------- */}
+
+ 验证--Immutable--
+ Counter: {counter}
+
+
+ {/* -----------------验证--castImmutable----------------------- */}
+
+ 验证castImmutable
+ castImmutable,期望值castImmutable为true时数据不可变
+ castImmutable:{produceStatus ? 'true' : 'false'}
+
+ Age: {data.age}
+
+
+ {/* -------------------验证--castDraft--- */}
+
+ 验证castDraft
+
+ castDraft,期望值使用castDraft函数确保新状态与原始状态不共享内存
+
+ Count: {castDraftState.count}
+
+
+ {/* ---------------验证--applyPatches-------------- */}
+
+ 验证applyPatches
+ 初始数据:{JSON.stringify(originalRes)}
+
+
+ 改变后数据:{JSON.stringify(obj1)}
+
+ 恢复的数据--{JSON.stringify(obj2)}
+
+
+
+ );
+};
+
+const styles = StyleSheet.create({
+ container: {
+ width: '100%',
+ justifyContent: 'center',
+ alignItems: 'center',
+ padding: 10,
+ marginBottom: 5,
+ borderWidth: 1,
+ },
+ text: {
+ width: '100%',
+ fontSize: 18,
+ marginBottom: 0,
+ textAlign: 'center',
+ fontWeight: '700',
+ margin: 5,
+ },
+ border: {
+ borderWidth: 1,
+ },
+});
+
+export default MyComponent;
+
+```
+
+## 兼容性
+
+在以下版本验证通过
+
+1. RNOH:0.72.13; SDK:HarmonyOS NEXT Developer Preview1; IDE:DevEco Studio 4.1.3.500; ROM:204.1.0.59;
+
+## API
+
+> | Name | Description | Required | Platform | HarmonyOS Support |
+> | ------------------------- | ------------------------------------------------------------ | -------- | ----------- | ----------------- |
+> | `(default)` | Immer 核心 API,通常命名为 `produce`: `import {produce} from "immer"` | NO | Android IOS | YES |
+> | `applyPatches` | 给定一个基本 state 或 draft,以及一组 patches ,应用 patches | NO | Android IOS | YES |
+> | `castDraft` | 将任何不可变类型转换为其可变对应物。这只是一个转换,实际上并没有做任何事情。 | NO | Android IOS | YES |
+> | `castImmutable` | 将任何可变类型转换为其不可变对应物。这只是一个转换,实际上并没有做任何事情。 | NO | Android IOS | YES |
+> | `createDraft` | 给定一个基本 state,创建一个可变 draft,任何修改都将被记录下来 | NO | Android IOS | YES |
+> | `current` | 给定一个 draft 对象(不必是对象的根结点),对 draft 的当前状态进行快照 | NO | Android IOS | YES |
+> | `Draft` | 暴露的 TypeScript 类型以将不可变类型转换为可变类型 | NO | Android IOS | YES |
+> | `enableMapSet()` | 启用对 `Map` 和 `Set` 集合的支持。 | NO | Android IOS | YES |
+> | `enablePatches()` | 启用对 JSON patches 的支持 | NO | Android IOS | YES |
+> | `finishDraft` | 给定使用 `createDraft` 创建的 draft,冻结 draft 并生成并返回下一个不可变状态,该状态捕获所有更改 | NO | Android IOS | YES |
+> | `freeze(obj, deep?)` | 冻结可 draft 对象。返回原始对象。默认情况下浅冻结,但如果第二个参数为真,它将递归冻结。 | NO | Android IOS | YES |
+> | `Immer` | 可用于创建第二个“immer”实例(暴露此实例中列出的所有 API)的构造函数,它不与全局实例共享其设置 | NO | Android IOS | YES |
+> | `immerable` | 可以添加到构造函数或原型的符号,表示 Immer 应该将类视为可以安全 draft 的东西 | NO | Android IOS | YES |
+> | `Immutable` | 暴露的 TypeScript 类型以将可变类型转换为不可变类型 | NO | Android IOS | YES |
+> | `isDraft` | 如果给定对象是 draft 对象,则返回 true | NO | Android IOS | YES |
+> | `isDraftable` | 如果 Immer 能够将此对象变成 draft,则返回 true。这适用于:数组、没有原型的对象、以 `Object` 为原型的对象、在其构造函数或原型上具有 `immerable` 符号的对象 | NO | Android IOS | YES |
+> | `nothing` | 可以从 recipe 返回的值,以指示应生成 `undefined` | NO | Android IOS | YES |
+> | `original` | 给定一个 draft 对象(不必是对象的根结点),返回原始状态树中相同路径的原始对象(如果存在) | NO | Android IOS | YES |
+> | `Patch` | 暴露的 TypeScript 类型,描述(反向)patches 对象的形状 | NO | Android IOS | YES |
+> | `produce` | Immer 的核心 API,也暴露为 `default` 导出 | NO | Android IOS | YES |
+> | `produceWithPatches` | 与 `produce` 相同,但它不仅返回生成的对象,还返回一个由 `[result, patch, inversePatches]` 组成的元组 | NO | Android IOS | YES |
+> | `setAutoFreeze` | 启用/禁用递归的自动冻结。默认启用 | NO | Android IOS | YES |
+> | `setUseStrictShallowCopy` | 可用于启用严格浅拷贝,如果启用,immer将尽可能多地复制不可枚举属性 | NO | Android IOS | YES |
+
+## 遗留问题
+
+## 其他
--
Gitee