javascript - 反应原生 0.63.3 | 使用 chrome 调试器时 setInterval 不起作用
问题描述
我有一个严重依赖间隔和超时的专有应用程序。当我尝试调试间隔之前/之后发生的问题时,没有任何效果,因为间隔永远不会触发。
这是我如何使用间隔的片段(假设所有功能都已实现):
useEffect(() => {
let timerInterval;
const stopTimer = () => {
clearInterval(timerInterval);
};
subTimerStarted(() => {
stopTimer();
timerInterval = setInterval(() => {
tick();
if (store.getState().time <= 0) {
clearInterval(timerInterval);
}
}, 1000);
});
subTimerReset(stopTimer);
}, []);
当 chrome 调试器处于活动状态setInterval
时,将永远不会触发。研究告诉我,这是因为我的工作站和设备的时钟不同步。我不明白为什么这应该是一个问题,因为设备应该完成所有工作,并且只是向调试器发送信号,通知它它的当前状态。这是不可接受的,我需要正确访问调用堆栈来解决这些问题。
我已经看过的资源:
- https://fantashit.com/settimeout-and-setinterval-don-t-fire-on-android-rn-0-31-when-attached-to-chrome-debugger/
- setInterval 和 setTimeout 都不起作用 react-native ES6
- https://github.com/facebook/react-native/issues/20351
- https://github.com/facebook/react-native/issues/9436
- https://github.com/facebook/react-native/issues/29591
- https://github.com/fractaltech/react-native-timer
- https://github.com/facebook/react-native/issues/26828
非选项:
- 使用和安卓模拟器
- react-native-debugger (不会让任何事情变得更好)
- 反应加速器
- 任何以“just”开头的解决方案
细节
由于 NDA,我不能展示太多,除了那个代码示例 ^ 和这些:
包.json
{
"main": "index.js",
"scripts": {
"android": "react-native run-android",
"ios": "react-native run-ios",
"web": "expo start --web",
"start": "react-native start --reset-cache",
"test": "jest",
},
"dependencies": {
"@apollo/client": "^3.3.9",
"@react-native-community/masked-view": "^0.1.10",
"@react-navigation/native": "^5.8.1",
"@react-navigation/stack": "^5.11.0",
"bluebird": "^3.7.2",
"buffer": "^6.0.3",
"color": "^3.1.3",
"expo": "~39.0.2",
"expo-splash-screen": "~0.6.2",
"expo-status-bar": "~1.0.2",
"expo-updates": "~0.3.2",
"graphql": "^15.5.0",
"lodash.ismatch": "^4.4.0",
"react": "16.13.1",
"react-dom": "16.13.1",
"react-native": "~0.63.3",
"react-native-cookies": "^3.3.0",
"react-native-exit-app": "^1.1.0",
"react-native-fs": "^2.16.6",
"react-native-gesture-handler": "~1.7.0",
"react-native-reanimated": "~1.13.0",
"react-native-restart": "0.0.20",
"react-native-safe-area-context": "^3.1.9",
"react-native-screens": "~2.10.1",
"react-native-share": "^5.1.0",
"react-native-sidebar": "^0.3.0",
"react-native-svg": "^12.1.0",
"react-native-svg-transformer": "^0.14.3",
"react-native-unimodules": "~0.11.0",
"react-native-uuid": "^1.4.9",
"react-native-vector-icons": "^7.1.0",
"react-native-web": "~0.13.12",
"react-native-webview": "^11.0.2",
"react-redux": "^7.2.2",
"redux": "^4.0.5",
"redux-thunk": "^2.3.0",
"regression": "^2.0.1"
},
"devDependencies": {
"@babel/core": "~7.9.0",
"babel-jest": "~25.2.6",
"jest": "~25.2.6",
"react-test-renderer": "~16.13.1"
},
"jest": {
"preset": "react-native"
},
"private": true,
"version": "1.0.0"
}
react-native info ~/Documents/node/obm-app
info Fetching system and libraries information...
(node:1581462) Warning: Accessing non-existent property 'padLevels' of module exports inside circular dependency
(Use `node --trace-warnings ...` to show where the warning was created)
System:
OS: Linux 5.10 Manjaro Linux
CPU: (20) x64 Intel(R) Core(TM) i9-10850K CPU @ 3.60GHz
Memory: 7.08 GB / 31.26 GB
Shell: 5.8 - /usr/bin/zsh
Binaries:
Node: 15.14.0 - /usr/local/bin/node
Yarn: 1.22.10 - /usr/bin/yarn
npm: 7.7.6 - /usr/local/bin/npm
Watchman: Not Found
SDKs:
Android SDK:
API Levels: 23, 25, 29, 30
Build Tools: 28.0.3, 29.0.2, 29.0.3, 30.0.3
System Images: android-25 | Google APIs Intel x86 Atom, android-29 | Google Play Intel x86 Atom, android-30 | Google APIs Intel x86 Atom
Android NDK: Not Found
IDEs:
Android Studio: 4.1 AI-201.8743.12.41.7199119
Languages:
Java: 1.8.0_292 - /usr/bin/javac
Python: 3.9.4 - /usr/bin/python
npmPackages:
@react-native-community/cli: Not Found
react: 16.13.1 => 16.13.1
react-native: ~0.63.3 => 0.63.4
npmGlobalPackages:
*react-native*: Not Found
解决方案
在做你正在做的事情时,我通常会使用一个全局变量。您可以在任何地方使用 clearInterval(timerInterval) 而无需将其保存到状态。
let timerInterval; //<-- timer variable here
const Component = () => {
useEffect(() => {
//stopTimer(); <-- u don't need this since u r running this useEffect only on mounted.
timerInterval = setInterval(() => {
tick();
if (store.getState().time <= 0) {
clearInterval(timerInterval);
}
}, 1000);
// subTimerReset(stopTimer); //<- don't need this
() => { clearInterval(timeInterval) } //<-- clean up function
}, []);
...
}
顺便说一句,您是否尝试将函数保存到状态?
subTimerReset(stopTimer)
推荐阅读
- node.js - React 应用程序在多个异步图像下载时重新加载
- node.js - Node.js Lambda 函数中的 AWS S3 ListObjects
- ms-access - 使用 VB6 连接到 Access 2013 数据库
- java - 我正在尝试公开一个 ArrayList(在 java 中),以便我可以在不同的类中访问它,我做错了什么?
- python - pip install 失败“找不到满足要求的版本”
- sql - 计算客户购买商品的平均价格
- angular - 使用 Injectable service 洞察另一个 Injectable service angular 5
- mysql - msql 将每个类别中的项目计数为 2 列,按状态与连接
- python - 灰度图像到 3 个通道
- android - Kotlin 升级后的顶级声明除外