已合并
docs:update infomation for 0.72 #37
已合并
LiQiang创建于 8月20日
共 7 个文件变更+992-11
MREADME.md+490-7
@@ -1,13 +1,496 @@
1-# @react-native-ohos/react-native-background-timer1+> 文档模板:v0.4.2
2 2 
3-This project is based on [react-native-background-timer](https://github.com/ocetnik/react-native-background-timer)@2.4.13+<p align="center">
4+ <h1 align="center"> <code>react-native-background-timer</code> </h1>
5+</p>
4 6 
5-## Documentation7+本项目基于 [react-native-background-timer](https://github.com/ocetnik/react-native-background-timer) 开发。
6 8 
7-- [中文](https://gitcode.com/OpenHarmony-RN/usage-docs/blob/master/zh-cn/react-native-background-timer.md)9+该第三方库的仓库已迁移至 Gitcode,且支持直接从 npm 下载,新的包名为:`@react-native-ohos/react-native-background-timer` 版本所属关系如下:
8 10 
9-- [English](https://gitcode.com/OpenHarmony-RN/usage-docs/blob/master/en/react-native-background-timer.md)11+| 三方库名称 | 三方库版本(npm地址) | 发布信息 | 支持RN版本 | Autolink | 编译API版本 | 社区基线版本 | 源码地址 |
12+| ------------ | ------------ | ------------------------------ | ------------- | ------------- |------------------------ | ------------- | ------------- |
13+| @react-native-ohos/react-native-background-timer | [~ 2.4.2](https://www.npmjs.com/package/@react-native-ohos/react-native-background-timer) | [Gitcode Releases](https://gitcode.com/CPF-RN/rntpc_react-native-background-timer/releases) | 0.72.* | 是 | API12+ | v2.4.1 | [br_rnoh0.72](https://gitcode.com/CPF-RN/rntpc_react-native-background-timer/tree/br_rnoh0.72) |
14+| @react-native-oh-tpl/react-native-background-timer | [<= 2.4.1-0.0.2@deprecated](https://www.npmjs.com/package/@react-native-oh-tpl/react-native-background-timer) | [Github Releases(deprecated)](https://github.com/react-native-oh-library/react-native-background-timer/releases) | 0.72.* | 否 | API12+ | v2.4.1 | [sig](https://github.com/react-native-oh-library/react-native-background-timer/tree/sig) |
10 15 
11-## License16+## 简介
12 17 
13-This library is licensed under [The MIT License (MIT)](https://gitee.com/openharmony-sig/rntpc_react-native-background-timer/blob/master/LICENSE)18+定期触发事件(即使应用处于后台运行状态)。
19+ 
20+## 下载安装
21+ 
22+进入到工程目录并输入以下命令:
23+ 
24+**npm**
25+ 
26+```bash
27+npm install @react-native-ohos/react-native-background-timer
28+```
29+ 
30+**yarn**
31+ 
32+```bash
33+yarn add @react-native-ohos/react-native-background-timer
34+```
35+ 
36+## Link
37+ 
38+| | 是否支持autolink | RN框架版本 |
39+|--------------------------------------|-----------------|-----------|
40+| ~2.4.2 | Yes | 0.72 |
41+| <= 2.4.1-0.0.2@deprecated | No | 0.72 |
42+ 
43+使用AutoLink的工程需要根据该文档配置,Autolink框架指导文档:https://gitcode.com/CPF-RN/ohos_react_native/blob/master/docs/zh-cn/Autolinking.md
44+ 
45+如您使用的版本支持 Autolink,并且工程已接入 Autolink,可跳过ManualLink配置。
46+ 
47+### 必要的配置项
48+ 
49+> [!TIP] 该模块的内容无法通过autolink自动生成,始终需要手动配置。
50+ 
51+### 配置TurboModule运行在worker线程(该模块始终需要手动配置)
52+ 
53+打开 `entry/src/main/ets/entryability/EntryAbility.ets`,添加:
54+ 
55+```diff
56+import {RNAbility} from '@rnoh/react-native-openharmony';
57+ 
58+export default class EntryAbility extends RNAbility {
59++ override getRNOHWorkerScriptUrl() {
60++ return "entry/ets/workers/RNOHWorker.ets"
61++ }
62+...
63+}
64+```
65+ 
66+在ets路径下右击,选择 `New` 选项,右侧展开菜单选择 `Worker` 选项:
67+ 
68+ ![create_worker](./img/create-worker.png)
69+ 选择后在弹出的窗口中取名 `RNOHWorker.ets`:
70+ 
71+ ![christen_RNOHWorker](./img/christen-RNOHWorker.png)
72+ 此时目录结构为:
73+ ```
74+ └── ets
75+ ├── entryability
76+ ├── page
77+ └── workers
78+ └── RNOHWorker.ets
79+ ```
80+ 修改 `RNOHWorker.ets` 为下列代码:
81+ ```typescript
82+ // entry/src/main/ets/workers/RNOHWorker.ets
83+ import { setupRNOHWorker } from "@rnoh/react-native-openharmony/src/main/ets/setupRNOHWorker";
84+ import { createRNPackages } from '../RNPackagesFactory';
85+ 
86+ setupRNOHWorker({
87+ createWorkerRNInstanceConfig: (_rnInstanceName) => {
88+ return { thirdPartyPackagesFactory: createRNPackages }
89+ }
90+ })
91+ ```
92+ 
93+<details>
94+ <summary>ManualLink: 此步骤为手动配置原生依赖项的指导</summary>
95+ 
96+首先需要使用 DevEco Studio 打开项目里的 HarmonyOS 工程 `harmony`。
97+ 
98+### 1. Overrides RN SDK
99+ 
100+为了让工程依赖同一个版本的 RN SDK,需要在工程根目录的 `oh-package.json5` 添加 overrides 字段,指向工程需要使用的 RN SDK 版本。替换的版本既可以是一个具体的版本号,也可以是一个模糊版本,还可以是本地存在的 HAR 包或源码目录。
@@ -0,0 +1,498 @@
1+> Document Template: v0.4.2
2+ 
3+<p align="center">
4+ <h1 align="center"> <code>react-native-background-timer</code> </h1>
5+</p>
6+ 
7+This project is based on [react-native-background-timer](https://github.com/ocetnik/react-native-background-timer).
8+ 
9+This third-party library has been migrated to Gitcode and is now available for direct download from npm, the new package name is: `@react-native-ohos/react-native-background-timer`, The version correspondence details are as follows:
10+ 
11+| Name | Version(Npm Address) | Release Information | Supported RN Version | Supported Autolink | Compile API Version | Community Baseline Version | Source code address |
12+| --------------| -------------- | ------------------------------ | ------------- | ------------- |------------------------ | ------------ | ------------- |
13+| @react-native-ohos/react-native-background-timer | [~ 2.4.2](https://www.npmjs.com/package/@react-native-ohos/react-native-background-timer) | [Gitcode Releases](https://gitcode.com/CPF-RN/rntpc_react-native-background-timer/releases) | 0.72.* | Yes | API12+ | v2.4.1 | [br_rnoh0.72](https://gitcode.com/CPF-RN/rntpc_react-native-background-timer/tree/br_rnoh0.72) |
14+| @react-native-oh-tpl/react-native-background-timer | [<= 2.4.1-0.0.2@deprecated](https://www.npmjs.com/package/@react-native-oh-tpl/react-native-background-timer) | [Github Releases(deprecated)](https://github.com/react-native-oh-library/react-native-background-timer/releases) | 0.72.* | No | API12+ | v2.4.1 | [sig](https://github.com/react-native-oh-library/react-native-background-timer/tree/sig) |
15+ 
16+## Introduction
17+ 
18+Emit event periodically (even when app is in the background).
19+ 
20+## Installation
21+ 
22+Go to the project directory and execute the following instruction:
23+ 
24+**npm**
25+ 
26+```bash
27+npm install @react-native-ohos/react-native-background-timer
28+```
29+ 
30+**yarn**
31+ 
32+```bash
33+yarn add @react-native-ohos/react-native-background-timer
34+```
35+ 
36+## Link
37+ 
38+| | Supported Autolink | Supported RN Version |
39+|--------------------------------------|--------------------|----------------------|
40+| ~2.4.2 | Yes | 0.72 |
41+| <= 2.4.1-0.0.2@deprecated | No | 0.72 |
42+ 
43+Projects using AutoLink need to be configured according to this document, AutoLink framework guide: https://gitcode.com/CPF-RN/ohos_react_native/blob/master/docs/zh-cn/Autolinking.md
cpf-managercpf-manager
cpf-managercpf-manager8月21日

【AI-Review】【一般】【基础代码问题】【代码逻辑错误】英文 README 的 Autolink 指南链接指向中文文档

● 问题:README_en.md 第43行将 Autolink 框架指南链接指向 https://gitcode.com/CPF-RN/ohos_react_native/blob/master/docs/zh-cn/Autolinking.md,该 URL 路径包含 zh-cn,是中文版文档。README_en.md 是面向英文用户的文档,英文用户点击该链接后会进入中文页面,无法理解内容。通过 GitCode API 验证(GET /api/v5/repos/CPF-RN/ohos_react_native/contents/docs/en?ref=master),ohos_react_native 仓库的 docs/en/ 目录下不存在 Autolinking.md 文件,该目录仅有 Codegen.md、TurboModule.md、architecture.md 等文件,即 Autolink 指南目前仅有中文版,没有对应的英文翻译。

● 影响:一般。英文用户按照文档操作时,点击 Autolink 指南链接会进入中文页面,无法获取英文操作指导,影响文档可用性。

● 建议:在链接后补充说明该指南目前仅提供中文版,例如:"AutoLink framework guide (currently available in Chinese only): https://gitcode.com/CPF-RN/ohos_react_native/blob/master/docs/zh-cn/Autolinking.md",待英文版翻译完成后更新为 docs/en/Autolinking.md 链接。

likedislike
LiQiang
8月22日 评论:
cpf-managercpf-manager8月22日

【AI-Review】【一般】【基础代码问题】【可读性问题】英文版 README 链接到中文版 Autolinking 文档

● 问题: 第43行 AutoLink 框架指导文档的链接指向 docs/zh-cn/Autolinking.md(中文版),但当前文件是英文 README(README_en.md)。英文版文档中的链接应指向英文版 Autolinking 文档。经验证,英文版 Autolinking 文档存在于 https://gitcode.com/CPF-RN/ohos_react_native/blob/master/docs/en/Autolinking.md(HTTP 200)。

触发路径:英文用户阅读 README_en.md → 点击第43行 "AutoLink framework guide" 链接 → 跳转到中文版 Autolinking.md(docs/zh-cn/Autolinking.md)→ 用户无法阅读中文文档,无法获取 Autolink 配置指导。

对比:同文件第145行的 "Directly Linking Source Code" 链接正确指向了英文版 usage-docs/blob/master/en/link-source-code.md,说明项目存在英文版文档惯例(/en/ 路径),第43行未遵循此惯例。

● 影响: 一般。英文用户无法正常使用 Autolink 配置文档,影响接入体验。

● 建议: 将第43行链接中的 zh-cn 改为 en: Projects using AutoLink need to be configured according to this document, AutoLink framework guide: https://gitcode.com/CPF-RN/ohos_react_native/blob/master/docs/en/Autolinking.md

likedislike
LiQiang
8月22日 评论:
44+ 
45+If the version you are using supports Autolink and the project has integrated Autolink, you can skip the ManualLink configuration.
46+ 
47+### Necessary configuration items
48+ 
49+> [!TIP] The content of this module cannot be automatically generated by autolink and must always be manually configured.
50+ 
51+### Configure TurboModule to run on worker thread(This module always requires manual configuration)
52+ 
53+Open the `entry/src/main/ets/entryability/EntryAbility.ets`file and add the following code:
54+ 
55+```diff
56+import {RNAbility} from '@rnoh/react-native-openharmony';
57+ 
58+export default class EntryAbility extends RNAbility {
59++ override getRNOHWorkerScriptUrl() {
60++ return "entry/ets/workers/RNOHWorker.ets"
61++ }
62+...
63+}
64+```
65+ 
66+Right click on the ETS path and select the `New` option. Expand the menu on the right and choose the `Worker` option:
67+ 
68+ ![create_worker](./img/create-worker.png)
69+ After selection, name `RNOHWorker.ets` in the pop-up window:
70+ 
71+ ![christen_RNOHWorker](./img/christen-RNOHWorker.png)
72+ At this point, the directory structure is:
73+ ```
74+ └── ets
75+ ├── entryability
76+ ├── page
77+ └── workers
78+ └── RNOHWorker.ets
79+ ```
80+ 
81+ Modify `RNOHWorker.ets` to the following code:
82+ ```typescript
83+ // entry/src/main/ets/workers/RNOHWorker.ets
84+ import { setupRNOHWorker } from "@rnoh/react-native-openharmony/src/main/ets/setupRNOHWorker";
85+ import { createRNPackages } from '../RNPackagesFactory';
86+ 
87+ setupRNOHWorker({
88+ createWorkerRNInstanceConfig: (_rnInstanceName) => {
89+ return { thirdPartyPackagesFactory: createRNPackages }
90+ }
91+ })
92+ ```
93+ 
94+<details>
95+ <summary>ManualLink: This step provides guidance for manually configuring native dependencies.</summary>
96+ 
97+Open the `harmony` directory of the OpenHarmony project in DevEco Studio.
98+ 
99+### 1. Overrides RN SDK
100+ 
101+To ensure the project relies on the same version of the RN SDK, you need to add an `overrides` field in the project's root `oh-package.json5` file, specifying the RN SDK version to be used. The replacement version can be a specific version number, a semver range, or a locally available HAR package or source directory.
102+ 
103+For more information about the purpose of this field, please refer to the [official documentation](https://developer.huawei.com/consumer/en/doc/harmonyos-guides-V5/ide-oh-package-json5-V5#en-us_topic_0000001792256137_overrides).
104+ 
105+```json
106+{
107+ "overrides": {
108+ "@rnoh/react-native-openharmony": "^0.72.139" // ohpm version
109+ // "@rnoh/react-native-openharmony" : "./react_native_openharmony.har" // a locally available HAR package
110+ // "@rnoh/react-native-openharmony" : "./react_native_openharmony" // source code directory
111+ }
112+}
113+```
114+ 
115+### 2. Introducing Native Code
116+ 
117+Currently, two methods are available:
118+ 
119+- Use the HAR file.
120+- Directly link to the source code.
121+ 
122+Method 1 (recommended): Use the HAR file.
123+ 
124+> [!TIP] The HAR file is stored in the `harmony` directory in the installation path of the third-party library.
125+ 
126+Open `entry/oh-package.json5` file and add the following dependencies:
127+ 
128+```json
129+"dependencies": {
130+ "@react-native-ohos/react-native-background-timer": "file:../../node_modules/@react-native-ohos/react-native-background-timer/harmony/background_timer.har"
131+ }
132+```
133+ 
134+Click the `sync` button in the upper right corner.
135+ 
136+Alternatively, run the following instruction on the terminal:
137+ 
138+```bash
139+cd entry
140+ohpm install
141+```
142+ 
143+Method 2: Directly link to the source code.
144+ 
145+> [!TIP] For details, see [Directly Linking Source Code](https://gitcode.com/CPF-RN/usage-docs/blob/master/en/link-source-code.md).
146+ 
147+### 3. Configuring CMakeLists and Introducing ReactNativeOhosReactNativeBackgroundTimerPackage
148+ 
149+Open `entry/src/main/cpp/CMakeLists.txt` and add the following code:
150+ 
151+```diff
152+project(rnapp)
153+cmake_minimum_required(VERSION 3.4.1)
154+set(CMAKE_SKIP_BUILD_RPATH TRUE)
155+set(RNOH_APP_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
156+set(NODE_MODULES "${CMAKE_CURRENT_SOURCE_DIR}/../../../../../node_modules")
157++ set(OH_MODULES "${CMAKE_CURRENT_SOURCE_DIR}/../../../oh_modules")
158+set(RNOH_CPP_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../react-native-harmony/harmony/cpp")
159+set(LOG_VERBOSITY_LEVEL 1)
160+set(CMAKE_ASM_FLAGS "-Wno-error=unused-command-line-argument -Qunused-arguments")
161+set(CMAKE_CXX_FLAGS "-fstack-protector-strong -Wl,-z,relro,-z,now,-z,noexecstack -s -fPIE -pie")
162+set(WITH_HITRACE_SYSTRACE 1) # for other CMakeLists.txt files to use
163+add_compile_definitions(WITH_HITRACE_SYSTRACE)
164+ 
165+add_subdirectory("${RNOH_CPP_DIR}" ./rn)
166+ 
167+# RNOH_BEGIN: manual_package_linking_1
168+add_subdirectory("../../../../sample_package/src/main/cpp" ./sample-package)
169++ add_subdirectory("${OH_MODULES}/@react-native-ohos/react-native-background-timer/src/main/cpp" ./background_timer)
170+# RNOH_END: manual_package_linking_1
171+ 
172+file(GLOB GENERATED_CPP_FILES "./generated/*.cpp")
173+ 
174+add_library(rnoh_app SHARED
175+ ${GENERATED_CPP_FILES}
176+ "./PackageProvider.cpp"
177+ "${RNOH_CPP_DIR}/RNOHAppNapiBridge.cpp"
178+)
179+target_link_libraries(rnoh_app PUBLIC rnoh)
180+ 
181+# RNOH_BEGIN: manual_package_linking_2
182+target_link_libraries(rnoh_app PUBLIC rnoh_sample_package)
183++ target_link_libraries(rnoh_app PUBLIC rnoh_background_timer)
184+# RNOH_END: manual_package_linking_2
185+```
186+ 
187+Open `entry/src/main/cpp/PackageProvider.cpp` and add the following code:
188+ 
189+```diff
190+#include "RNOH/PackageProvider.h"
191+#include "SamplePackage.h"
192++ #include "ReactNativeOhosReactNativeBackgroundTimerPackage.h"
193+ 
194+using namespace rnoh;
195+ 
196+std::vector<std::shared_ptr<Package>> PackageProvider::getPackages(Package::Context ctx) {
197+ return {
198+ std::make_shared<SamplePackage>(ctx),
199++ std::make_shared<BackgroundTimerPackage>(ctx)
200+ };
201+}
202+```
203+ 
204+### 4. Introducing BackgroundTimerTurboModulePackage to ArkTS
205+ 
206+Open `entry/src/main/ets/RNPackagesFactory.ts` and add:
207+ 
208+```diff
209+ ...
210++ import { BackgroundTimerTurboModulePackage } from '@react-native-ohos/react-native-background-timer/ts';
211+ 
212+export function createRNPackages(ctx: RNPackageContext): RNPackage[] {
213+ return [
214++ new BackgroundTimerTurboModulePackage(ctx)
215+ ];
216+}
217+```
218+</details>
219+ 
220+## Running
221+ 
222+Click the `sync` button in the upper right corner.
223+ 
224+Alternatively, run the following instruction on the terminal:
225+ 
226+```bash
227+cd entry
228+ohpm install
229+```
230+ 
231+Then build and run the code.
232+ 
233+ 
234+## Constraints
235+ 
236+### Compatibility
237+ 
238+This document is verified based on the following versions:
239+ 
240+1. RNOH: 0.72.96; SDK: HarmonyOS 6.0.0 Release SDK; IDE: DevEco Studio 6.0.0.858; ROM: 6.0.0.112;
241+2. RNOH: 0.72.33; SDK: HarmonyOS NEXT B1; IDE: DevEco Studio: 5.0.3.900; ROM: Next.0.0.71;
cpf-manager
cpf-managercpf-manager29 天前

【AI-Review】【一般】【基础代码问题】【代码逻辑错误】兼容性验证版本与依赖声明不一致

● 问题:README_en.md 第241行声明 "RNOH: 0.72.33" 为文档验证通过的版本。但 harmony/background_timer/oh-package.json5 第9行声明依赖 @rnoh/react-native-openharmony: ^0.72.38,根目录 package.json 第43行也声明 react-native-harmony: npm:@react-native-oh/react-native-harmony@^0.72.38。semver 范围 ^0.72.38 要求版本 >=0.72.38 且 <0.73.0,而 0.72.33 < 0.72.38,不满足该范围。

● 影响:一般。用户根据 README 兼容性说明,在工程中使用 RNOH 0.72.33 版本,执行 ohpm install 安装本库时,ohpm 会因 @rnoh/react-native-openharmony 版本不满足 ^0.72.38 而报依赖冲突错误,导致安装失败。文档声明的验证版本与实际依赖要求不一致,会误导用户。

● 建议:将第2条验证版本中的 RNOH 版本更新为满足 ^0.72.38 要求的版本(>=0.72.38),或者如果确实需要在低版本上验证,则需同步下调 oh-package.json5 和 package.json 中的最低依赖版本。推荐保持依赖声明不变,更新 README 中的验证版本为实际验证过的 >=0.72.38 版本。

likedislike
LiQiang
29 天前 评论:
242+ 
243+### Permission Requirements
244+ 
245+None
246+ 
247+## Example
248+ 
249+The following code shows the basic use scenario of the repository:
250+ 
251+> [!WARNING] The name of the imported repository remains unchanged.
252+ 
253+```javascript
254+import {View, Button, StyleSheet, Text,TextInput} from 'react-native';
255+import React, {useState} from 'react';
256+import BackgroundTimer from "react-native-background-timer";
257+export function BackgroundTimerExample() {
258+ let [count, setCount] = useState(0);
259+ let [text, setText] = useState("");
260+ let [delay, setDelay] = useState("1000");
261+ let [timeoutDelay, setTimeoutDelay] = useState("1000");
262+ let [intervalDelay, setIntervalDelay] = useState("1000");
263+ let timeoutList:number[] = []
cpf-manager
cpf-managercpf-manager8月20日

【AI-Review】【严重】【基础代码问题】【代码逻辑错误】示例代码 timeoutList 未持久化导致 clearTimeout 失效

● 问题:README_en.md 第263行将 timeoutList 声明为函数组件体内的普通局部变量 let timeoutList:number[] = [],而非使用 useState 或 useRef。在 React 函数组件中,每次 re-render 都会重新执行函数体并创建一个新的空数组。执行路径如下:用户点击 "setTimeout" 按钮 → setTimeoutStart(第279行)执行,将 timeoutId push 到当前渲染的 timeoutList → 随后 setText("Turn on the timer...")(第280行)触发 re-render → 新渲染产生新的空 timeoutList,原数组(含已 push 的 timeoutId)丢失 → 用户点击 "clearTimeout" 按钮 → setTimeoutStop(第286行)读取的是新渲染产生的空 timeoutList → timeoutList.length>0(第288行)为 false → BackgroundTimer.clearTimeout(第289行)永远不会被执行。同文件第264行对功能等价的 intervalList 正确使用了 useState,可佐证 timeoutList 的写法与设计意图不一致。

● 影响:严重。用户复制该示例代码运行后,"clearTimeout" 按钮点击后定时器不会被清除,后台仍持续触发回调。这与示例预期行为不符,会让用户误以为 BackgroundTimer.clearTimeout 接口无效。

● 建议:将 timeoutList 改为 useState 持久化存储,与 intervalList 保持一致:

let [timeoutList, setTimeoutList] = useState<number[]>([]);
// In setTimeoutStart:
setTimeoutList(prev => [...prev, timeoutId]);
// In setTimeoutStop:
if (timeoutList.length > 0) {
  BackgroundTimer.clearTimeout(timeoutList[0]);
  setTimeoutList(prev => prev.slice(1));
}
likedislike
LiQiang
8月21日 评论:
264+ let [intervalList, setIntervalList] = useState<number[]>([]);
265+
266+ // runBackgroundTimer
267+ function onPressStart(){
268+ setText("Turn on the timer...")
269+ BackgroundTimer.runBackgroundTimer(()=>{
270+ setCount(count+=1)
cpf-manager
cpf-managercpf-manager8月21日

【AI-Review】【一般】【基础代码问题】【代码逻辑错误】setCount(count+=1) 直接修改 state 变量导致定时器运行中 Reset 后计数跳变

● 问题:README_en.md 第270行 runBackgroundTimer 的回调中使用 setCount(count+=1) 直接修改 state 变量 count。该回调在 onPressStart(第267行)调用时创建,闭包捕获的是当时 render 的 count 变量。由于 runBackgroundTimer 会持续按 delay 间隔触发该回调,每次触发执行 count+=1 都在修改闭包中的 count 变量,而该变量与 React 内部 state 是两份独立的数据。当用户在定时器运行期间点击 "Reset" 按钮(第309-312行 resetNumber 调用 setCount(0)),React state 被重置为 0,但定时器回调仍闭包引用旧的 count 变量(此时已被多次自增到较大值,如 5)。下一次定时器触发时:count+=1 将闭包中的 count 从 5 变为 6,setCount(6) 使显示值从 0 直接跳到 6,而非从 0 重新开始。同样的 setCount(count+=1) 写法也出现在第298行 setInterval 回调中,存在相同问题。

● 影响:一般。用户在定时器运行期间点击 Reset 后,计数器不会从 0 重新开始递增,而是跳变到定时器闭包中累积的旧值+1,与用户预期不符,示例代码行为不正确。

● 建议:使用函数式更新获取最新 state,避免直接修改 state 变量: BackgroundTimer.runBackgroundTimer(() => { setCount(prev => prev + 1) }, parseInt(delay)) 第298行 setInterval 回调也应同样修改为 setCount(prev => prev + 1)。

likedislike
LiQiang
8月22日 评论:
271+ },parseInt(delay))
272+ }
273+ function onPressStop(){
274+ setText("Turn off the timer")
275+ BackgroundTimer.stopBackgroundTimer()
276+ }
277+ 
278+ // setTimeout
279+ function setTimeoutStart(){
280+ setText("Turn on the timer...")
281+ let timeoutId = BackgroundTimer.setTimeout(()=>{
282+ setCount(count+=1)
283+ },parseInt(timeoutDelay))
284+ timeoutList.push(timeoutId)
285+ }
286+ function setTimeoutStop(){
287+ setText("Turn off the timer")
288+ if(timeoutList.length>0){
289+ BackgroundTimer.clearTimeout(timeoutList[0])
290+ timeoutList.shift()
291+ }
292+ }
293+ 
294+ // setInterval
295+ function setIntervalStart(){
296+ setText("Turn on the timer...")
297+ let intervalId = BackgroundTimer.setInterval(()=>{
298+ setCount(count+=1)
299+ },parseInt(intervalDelay))
300+ setIntervalList([...intervalList,intervalId])
301+ }
302+ function setIntervalStop(){
303+ setText("Turn off the timer")
304+ if(intervalList.length>0){
305+ BackgroundTimer.clearInterval(intervalList[0])
306+ intervalList.shift()
cpf-manager
cpf-managercpf-manager8月22日

【AI-Review】【一般】【基础代码问题】【代码逻辑错误】intervalList.shift() mutates React state without setState update

● 问题: Line 306 in setIntervalStop() calls intervalList.shift() which directly mutates the state array managed by useState without calling setIntervalList. intervalList is declared at line 264 via let [intervalList, setIntervalList] = useState<number[]>([]), making it React state that must be updated immutably. Array.prototype.shift() mutates the array reference in place and bypasses React's state update mechanism.

Trigger path: User clicks "setInterval" button → setIntervalStart() calls setIntervalList([...intervalList, intervalId]) correctly updating state immutably → UI shows the new interval. User clicks "clearInterval" button → setIntervalStop() executes: line 303 setText("Turn off the timer") triggers re-render → line 305 BackgroundTimer.clearInterval(intervalList[0]) clears the timer → line 306 intervalList.shift() mutates the state array in place without calling setIntervalList → React cannot detect the intervalList state change. Although setText triggers a re-render, the state update for intervalList is unreliable because it bypasses the setState channel, leading to UI-state desynchronization in subsequent operations (clicking setInterval/clearInterval again) or concurrent update scenarios.

● 影响: General. Directly mutating state is a React anti-pattern that can cause UI-state desynchronization: after clicking clearInterval, the UI may still show the cleared interval; subsequent setIntervalList calls may compute new values based on the in-place mutated old reference, causing list data corruption.

● 建议: Use setIntervalList to update immutably, replacing intervalList.shift(): setIntervalList(prev => prev.slice(1)); This allows React to properly detect the state change and trigger re-render.

likedislike
LiQiang
8月22日 评论:
307+ }
308+ }
309+ function resetNumber(){
310+ setCount(0)
311+ setText("")
312+ }
313+ return (
314+ <View style={{flexDirection: 'column', flex: 1,backgroundColor:'white'}}>
315+ <View style={styles.container}>
316+ <View style={styles.viewStyle}>
317+ <Button
318+ onPress={onPressStart}
319+ title="runBackgroundTimer"
320+ />
321+ <TextInput
322+ style={{ height: 40, borderColor: 'gray', borderWidth: 1 }}
323+ placeholder="BackgroundTimer delay"
324+ onChangeText={(value)=>{setDelay(value)}}
325+ value={delay}
326+ />
327+ </View>
328+ <View style={[styles.viewStyle]}>
329+ <Button
330+ onPress={onPressStop}
331+ title="stopBackgroundTimer"
332+ />
333+ </View>
334+ </View>
335+
336+ <View style={styles.container}>
337+ <View style={styles.viewStyle}>
338+ <Button
339+ onPress={setTimeoutStart}
340+ title="setTimeout"
341+ />
342+ <TextInput
343+ style={{ height: 40, borderColor: 'gray', borderWidth: 1 }}
344+ placeholder="setTimeout delay"
345+ onChangeText={(value)=>{setTimeoutDelay(value)}}
346+ value={timeoutDelay}
347+ />
348+ </View>
349+ <View style={[styles.viewStyle]}>
350+ <Button
351+ onPress={setTimeoutStop}
352+ title="clearTimeout"
353+ />
354+ </View>
355+ </View>
356+
357+ <View style={styles.container}>
358+ <View style={styles.viewStyle}>
359+ <Button
360+ onPress={setIntervalStart}
361+ title="setInterval"
362+ />
363+ <TextInput
364+ style={{ height: 40, borderColor: 'gray', borderWidth: 1 }}
365+ placeholder="setInterval delay"
366+ onChangeText={(value)=>{setIntervalDelay(value)}}
367+ value={intervalDelay}
368+ />
369+ </View>
370+ <View style={[styles.viewStyle]}>
371+ <Button
372+ onPress={setIntervalStop}
373+ title="clearInterval"
374+ />
375+ </View>
376+ </View>
377+
378+ <View style={[styles.viewStyle,styles.resetStyle]}>
379+ <Button
380+ onPress={resetNumber}
381+ title="Reset"
382+ />
383+ </View>
384+ <Text style={styles.textStyle}>{count}</Text>
385+ <Text style={styles.textStyle}>{text}</Text>
386+ </View>
387+ );
388+}
389+ 
390+const styles = StyleSheet.create({
391+ container: {
392+ borderColor: 'black',
393+ borderTopWidth: 0,
394+ borderBottomWidth: 5,
395+ borderLeftWidth: 0,
396+ borderRightWidth: 0,
397+ padding: 10,
398+ },
399+ resetStyle: {
400+ paddingTop: 10,
401+ },
402+ viewStyle:{
403+ marginBottom: 10,
404+ },
405+ textStyle: {
406+ fontSize: 30,
407+ },
408+});
409+```
410+ 
411+## How to Use
412+ 
413+**Periodic background task**
414+ 
415+```javascript
416+// Start a background timer that executes the callback every `delay` milliseconds,
417+// even when the app is running in the background.
418+BackgroundTimer.runBackgroundTimer(() => {
419+ // Periodic task, e.g. polling data or updating a countdown
420+}, 2000);
421+ 
422+// Stop the background timer
423+BackgroundTimer.stopBackgroundTimer();
424+```
425+ 
426+**One-shot delayed task**
427+ 
428+```javascript
429+// Executes only once when the timer expires; still fires when the app is in the background
430+const timeoutId = BackgroundTimer.setTimeout(() => {
431+ // Delayed task, e.g. timeout reminder or delayed navigation
432+}, 3000);
433+ 
434+// Cancel it before the timer expires
435+BackgroundTimer.clearTimeout(timeoutId);
436+```
437+ 
438+**Repeating interval task**
439+ 
440+```javascript
441+// Repeats at a fixed interval; multiple timers can run simultaneously and independently,
442+// each returning its own timer ID
443+const intervalId = BackgroundTimer.setInterval(() => {
444+ // Repeating task, e.g. heartbeat reporting or polling refresh
445+}, 1000);
446+ 
447+// Stop the specified timer
448+BackgroundTimer.clearInterval(intervalId);
449+```
450+ 
451+## Available APIs
452+ 
453+> [!TIP] The **Platform** column indicates the platform where the properties are supported in the original third-party library.
454+ 
455+> [!TIP] If the value of **HarmonyOS Support** is **yes**, it means that the OpenHarmony platform supports this property; **no** means the opposite; **partially** means some capabilities of this property are supported. The usage method is the same on different platforms and the effect is the same as that of iOS or Android.
456+ 
457+### API
458+| Name | Type | Parameter Type | Return Value | Required | Platform | OpenHarmony Platform Support | Description |
459+|--------|-------|----------|---------|-------|--------|-----|-----------------|
460+| runBackgroundTimer | Function | callback: Function, delay: number | void | No | All | Yes | Starts a timer to repeatedly execute specified code at a fixed interval. |
461+| stopBackgroundTimer | Function | / | void | No | All | Yes | Stops the timer started by **runBackgroundTimer**. |
462+| start | Function | delay?: number | void | No | All | No | Starts a new task in the background. **delay** is optional and defaults to 0. |
463+| stop | Function | / | void | No | All | No | Stops a background task. |
464+| setTimeout | Function | callback: Function, timeout: number | number | No | All | Yes | Starts a timer to execute the specified code only once when the timer expires. |
465+| clearTimeout | Function | timeoutId: number | void | No | All | Yes | Stops the timer started by **setTimeout**. |
466+| setInterval | Function | callback: Function, timeout: number | number | No | All | Yes | Starts a timer to repeatedly execute specified code at a fixed interval. |
467+| clearInterval | Function | intervalId: number | void | No | All | Yes | Stops the timer started by **setInterval**. |
468+ 
469+## Known Issues
470+ 
471+- The underlying OS does not support RNOHContext serialized transfer in the new thread created by Worker. As a result, events cannot be sent in the new thread. The underlying OS framework needs to implement related service functionality. If no thread is started, the timer is not affected because **setTimeout** is an asynchronous method. The **start** and **stop** APIs of the Worker thread are not supported in HarmonyOS RN: [issue#2](https://gitcode.com/CPF-RN/rntpc_react-native-background-timer/issues/2).
472+ 
473+## Other
474+ 
475+None
476+ 
477+## Directory Structure
478+````
479+/rntpc_react-native-background-timer # Project root directory
480+├── harmony # HarmonyOS adaptation code
481+│ └─ background_timer.har # har package
482+│ └─ background_timer # HarmonyOS adaptation core code
483+│ └─ Index.ets # HarmonyOS adaptation code entry point
484+│ └─ src/main/ets
485+│ └─ BackgroundTimerTurboModule.ts # Background timer TurboModule file
486+├── src # React Native code
487+│ └─ RNBackgroundTimerSpec.ts # JS interface declaration file for the background timer TurboModule
488+├── README.md # Chinese installation and usage instructions
489+├── README_en.md # English installation and usage instructions
490+````
491+
492+## How to Contribute
493+ 
494+If you find any problem when using react-native-background-timer, submit an [issue](https://gitcode.com/CPF-RN/rntpc_react-native-background-timer/issues) or a [PR](https://gitcode.com/CPF-RN/rntpc_react-native-background-timer/pulls).
495+ 
496+## License
497+ 
498+The repository is based on [MIT License](https://gitcode.com/CPF-RN/rntpc_react-native-background-timer/blob/br_rnoh0.72/LICENSE).
@@ -4,7 +4,7 @@
4 {4 {
5 "name": 'default',5 "name": 'default',
6 "signingConfig": 'default',6 "signingConfig": 'default',
7- "compileSdkVersion": '5.0.1(13)',7+ "compileSdkVersion": '6.0.1(21)',
8 "compatibleSdkVersion": '5.0.0(12)',8 "compatibleSdkVersion": '5.0.0(12)',
9 "runtimeOS": 'HarmonyOS'9 "runtimeOS": 'HarmonyOS'
10 },10 },
@@ -8,7 +8,7 @@
8 "start": "hdc rport tcp:8081 tcp:8081 && react-native start",8 "start": "hdc rport tcp:8081 tcp:8081 && react-native start",
9 "codegen": "react-native codegen-harmony --rnoh-module-path ./harmony/entry/oh_modules/@rnoh/react-native-openharmony",9 "codegen": "react-native codegen-harmony --rnoh-module-path ./harmony/entry/oh_modules/@rnoh/react-native-openharmony",
10 "pack:pkg": "cd ../ && npm pack && cd ./example",10 "pack:pkg": "cd ../ && npm pack && cd ./example",
11- "install:pkg": "npm uninstall @react-native-ohos/react-native-background-timer && npm run pack:pkg && npm i @react-native-ohos/react-native-background-timer@file:../react-native-ohos-react-native-background-timer-2.4.2-rc.4.tgz",11+ "install:pkg": "npm uninstall @react-native-ohos/react-native-background-timer && npm run pack:pkg && npm i @react-native-ohos/react-native-background-timer@file:../react-native-ohos-react-native-background-timer-2.4.2.tgz",
12 "dev": "npm run codegen && react-native bundle-harmony --dev --minify=false",12 "dev": "npm run codegen && react-native bundle-harmony --dev --minify=false",
13 "prod": "npm run codegen && react-native bundle-harmony --dev=false --minify=true",13 "prod": "npm run codegen && react-native bundle-harmony --dev=false --minify=true",
14 "postinstall": "node ./scripts/create-build-profile",14 "postinstall": "node ./scripts/create-build-profile",
@@ -16,7 +16,7 @@
16 },16 },
17 "dependencies": {17 "dependencies": {
18 "@gorhom/portal": "^1.0.14",18 "@gorhom/portal": "^1.0.14",
19- "@react-native-ohos/react-native-background-timer": "file:../react-native-ohos-react-native-background-timer-2.4.2-rc.4.tgz",19+ "@react-native-ohos/react-native-background-timer": "file:../react-native-ohos-react-native-background-timer-2.4.2.tgz",
20 "react": "18.2.0",20 "react": "18.2.0",
21 "react-native": "0.72.5",21 "react-native": "0.72.5",
22 "react-native-harmony": "npm:@react-native-oh/react-native-harmony@^0.72.32"22 "react-native-harmony": "npm:@react-native-oh/react-native-harmony@^0.72.32"
@@ -1,7 +1,7 @@
1{1{
2 name: '@react-native-ohos/react-native-background-timer',2 name: '@react-native-ohos/react-native-background-timer',
3 version: '2.4.2',3 version: '2.4.2',
4- description: 'Please describe the basic information.',4+ description: 'Emit event periodically (even when app is in the background)',
5 main: 'Index.ets',5 main: 'Index.ets',
6 author: '',6 author: '',
7 license: 'MIT',7 license: 'MIT',