code-debugging
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseCode Debugging Skill
代码调试技能
Skill Purpose
技能用途
This skill specializes in debugging React Native code issues within the Ecalyptus healthcare mobile application. When you encounter bugs, crashes, unexpected behavior, or error messages, this skill helps identify root causes, explains why problems occur in the React Native environment, and provides targeted fixes. Once bugs are resolved, it can suggest when deeper refactoring would improve code quality and recommend engaging the Refactoring Skill for comprehensive improvements.
本技能专门用于调试Ecalyptus医疗移动应用中的React Native代码问题。当你遇到bug、崩溃、异常行为或错误提示时,本技能可帮助你定位根本原因,解释问题在React Native环境中出现的缘由,并提供针对性修复方案。问题解决后,它还会建议何时进行深度重构以提升代码质量,并推荐调用重构技能来完成全面优化。
Core Philosophy
核心理念
Debug First, Review Later: Critiquing code architecture while fundamental logic is broken is counterproductive. This skill prioritizes establishing working code before optimizing it. Think of it as ensuring a building's foundation is solid before renovating the interior.
Simplicity Over Cleverness: Readable, straightforward code is always preferred over advanced, complex solutions. When debugging, this skill focuses on reducing complexity first because complexity is often where bugs originate. Simple code fails in simple, obvious ways. Complex code fails in complex, hidden ways. A bug in a straightforward conditional is easy to spot and fix. A bug buried in nested abstractions, higher-order functions, or clever composition patterns takes hours to diagnose and days to fix safely. In a healthcare application where mistakes have real consequences, the developer debugging an issue at 2 AM needs to understand the code immediately, not spend time deciphering elegant but opaque logic.
Fix the Bug, Then Improve the Pattern: After resolving the immediate issue, assess whether a new code pattern would prevent similar bugs from recurring. Sometimes a bug reveals that the current approach is fundamentally fragile. In these cases, introduce a better pattern as part of the solution. But the pattern should serve clarity and maintainability, not showcase advanced techniques. Every new pattern must earn its place by making the code easier to understand and harder to break.
Teach, Don't Just Fix: Every bug is a learning opportunity. This skill explains the mental model behind issues so you understand not just what broke, but why it broke and how to prevent similar issues in the future.
Context-Aware Analysis: React Native has unique constraints compared to web development. This skill always explains why certain patterns fail in the React Native environment and suggests RN-compatible alternatives.
先调试,后优化:在基础逻辑存在问题时,对代码架构进行批评是徒劳的。本技能优先确保代码可正常运行,再进行优化。这就像先确保建筑地基牢固,再进行内部翻新一样。
简洁优于炫技:可读、直白的代码永远比复杂的高级方案更值得推崇。调试时,本技能首先聚焦于降低复杂度,因为bug往往源于复杂逻辑。简单代码的问题明显且易于修复,而复杂代码的问题则隐蔽且难以排查。在医疗应用中,错误会带来实际后果,凌晨2点调试问题的开发者需要立刻理解代码,而不是花费时间解读看似优雅却晦涩的逻辑。
先修复bug,再优化模式:解决当前问题后,评估是否需要引入新的代码模式来避免同类问题再次发生。有时bug会暴露当前方案的本质缺陷,这种情况下可在修复中引入更优模式。但模式必须服务于代码的清晰度和可维护性,而非展示高级技术。每一种新模式的引入都必须以提升代码可读性、降低出错风险为目标。
授人以渔,而非仅授人以鱼:每一个bug都是学习的机会。本技能会解释问题背后的思维模型,让你不仅知道哪里出了问题,还能理解问题产生的原因以及如何避免未来出现同类问题。
上下文感知分析:与Web开发相比,React Native有其独特的限制。本技能会始终解释某些模式在React Native环境中失效的原因,并提供兼容RN的替代方案。
Project Context Reference
项目上下文参考
This skill always refers to the Copilot Instructions at for project-specific patterns, architecture decisions, and conventions. Key patterns to remember:
.github/copilot-instructions.mdIntentional Patterns (Don't Flag These):
- RTK Query mutations using without
.then()blocks—error handling is centralized in.catch()middleware (queryErrorLogger)appSlice.ts - Dynamic base URL switching via in production versus fixed URLs in staging
dynamicBaseQuery - Path aliases for all imports (,
@components,@utils/*, etc.)—never relative paths@reducers/* - Colors via from
colors.palette.*—no hardcoded hex values@theme - Typed Redux hooks from —never plain
@hooks/app/useDispatchuseSelector
Architecture Anchors:
- Dual RTK Query APIs: for healthcare,
mainApifor inventorybackOfficeApi - React Native 0.79.5 with React 19 features available
- Expo SDK ~53 with New Architecture enabled ()
newArchEnabled: true - React Compiler enabled via
babel-plugin-react-compiler
When uncertain about code intention or project patterns, always ask for clarification rather than making assumptions.
本技能会始终参考中的Copilot指令,以遵循项目特定的模式、架构决策和约定。需要牢记的关键模式:
.github/copilot-instructions.md有意设计的模式(无需标记为问题):
- RTK Query mutations使用但不使用
.then()块——错误处理集中在.catch()中间件(queryErrorLogger)中appSlice.ts - 生产环境中通过动态切换基准URL, staging环境中使用固定URL
dynamicBaseQuery - 所有导入使用路径别名(、
@components、@utils/*等)——禁止使用相对路径@reducers/* - 颜色使用中的
@theme——禁止使用硬编码的十六进制值colors.palette.* - 使用中的类型化Redux钩子——禁止使用原生
@hooks/app/useDispatchuseSelector
架构核心:
- 双RTK Query API:用于医疗业务,
mainApi用于库存管理backOfficeApi - React Native 0.79.5,支持React 19特性
- Expo SDK ~53,启用新架构()
newArchEnabled: true - 通过启用React Compiler
babel-plugin-react-compiler
当对代码意图或项目模式不确定时,务必先请求澄清,而非自行假设。
Debugging Process
调试流程
Phase 1: Symptom Analysis
阶段1:症状分析
When you report a bug or unexpected behavior, the skill follows this investigation pattern:
Gather Context:
- What is the expected behavior?
- What actually happens instead?
- Are there error messages or stack traces?
- When does it occur (on mount, on interaction, on state change)?
- Which file and component are involved?
Initial Hypothesis:
Based on symptoms, form preliminary hypotheses about root causes. Common bug categories in React Native include:
- Async timing issues (race conditions, stale closures)
- State management problems (stale state, missing dependencies)
- React Native API misuse (web-only APIs, platform-specific behavior)
- Navigation state issues (unmounted component updates)
- Memory leaks (uncleared timers, subscriptions)
- RTK Query cache staleness or improper invalidation
当你报告bug或异常行为时,本技能会遵循以下调查模式:
收集上下文:
- 预期行为是什么?
- 实际发生了什么?
- 是否有错误提示或堆栈跟踪信息?
- 问题何时出现(组件挂载时、交互时、状态变更时)?
- 涉及哪些文件和组件?
初步假设:
根据症状,形成关于根本原因的初步假设。React Native中常见的bug类别包括:
- 异步时序问题(竞态条件、过时闭包)
- 状态管理问题(过时状态、缺失依赖项)
- React Native API误用(仅Web可用的API、平台特定行为)
- 导航状态问题(已卸载组件的更新操作)
- 内存泄漏(未清除的定时器、订阅)
- RTK Query缓存过期或无效配置
Phase 2: Root Cause Investigation
阶段2:根本原因调查
Analyze the Problematic Code:
The skill examines the specific code section you reference, looking for patterns that explain the symptoms. It considers:
React Native Environment Constraints:
- Does this code use web-only APIs that don't exist in React Native?
- Are there platform-specific behaviors (iOS vs Android differences)?
- Is this using deprecated React Native APIs?
React Rules Violations:
- Are hooks called conditionally or in loops?
- Are dependency arrays incomplete or incorrect?
- Is state being mutated directly instead of immutably?
Async Patterns:
- Are promises handled correctly with proper error handling?
- Could there be race conditions between multiple async operations?
- Are effects triggering updates on unmounted components?
RTK Query Issues:
- Is the query/mutation configured with proper cache tags?
- Are there missing or
providesTags?invalidatesTags - Is conditional fetching handled with ?
skipToken - Could multiple components be triggering unnecessary refetches?
Memory and Lifecycle:
- Are subscriptions, timers, or listeners being cleaned up?
- Could this component be updating state after unmounting?
- Are there circular dependencies causing memory leaks?
分析问题代码:
本技能会检查你提供的特定代码段,寻找能解释症状的模式。主要考虑以下方面:
React Native环境限制:
- 代码是否使用了React Native中不存在的仅Web可用API?
- 是否存在平台特定行为(iOS与Android差异)?
- 是否使用了已弃用的React Native API?
React规则违反:
- 是否在条件语句或循环中调用钩子?
- 依赖数组是否不完整或存在错误?
- 是否直接修改状态而非使用不可变更新?
异步模式:
- Promise是否得到正确处理并包含错误处理?
- 多个异步操作之间是否存在竞态条件?
- 副作用是否在组件卸载后仍触发更新?
RTK Query问题:
- 查询/突变是否配置了正确的缓存标签?
- 是否缺失或
providesTags?invalidatesTags - 是否使用处理条件式请求?
skipToken - 是否有多个组件触发不必要的重复请求?
内存与生命周期:
- 订阅、定时器或监听器是否已被清理?
- 组件卸载后是否仍在更新状态?
- 是否存在循环依赖导致内存泄漏?
Phase 3: Root Cause Explanation
阶段3:根本原因解释
Once the issue is identified, the skill explains:
What's Happening: Describe the bug in terms of program execution flow. Walk through what the code is actually doing step-by-step.
Why It's Happening: Explain the underlying reason. This often involves explaining React's mental model, JavaScript's async behavior, or React Native's platform differences.
Why This Pattern Fails in React Native: If the issue is RN-specific, explain what React Native lacks compared to web (like DOM APIs, certain browser features, etc.) and why the pattern breaks.
Example Root Cause Explanation:
The crash occurs because you're calling `document.getElementById()` inside your
component. This is a web-only API that doesn't exist in React Native.
Here's what's happening: React Native doesn't use a DOM (Document Object Model)
like web browsers do. Instead, it renders native mobile components directly.
When your code tries to call `document.getElementById()`, JavaScript throws a
ReferenceError because the `document` object simply doesn't exist in the React
Native runtime environment.
In web development, you use `document.getElementById()` to access DOM elements
directly. In React Native, you should use refs instead, which work the same way
across web and native platforms. The `useRef` hook gives you a reference to a
component instance without relying on browser-specific APIs.定位问题后,本技能会进行如下解释:
问题现象: 从程序执行流程的角度描述bug,逐步讲解代码实际的执行过程。
问题原因: 解释问题背后的根本原因,通常涉及React思维模型、JavaScript异步行为或React Native平台差异。
为何在React Native中失效: 如果问题是RN特有的,解释React Native与Web相比缺少哪些特性(如DOM API、特定浏览器功能等),以及为何该模式会失效。
根本原因解释示例:
崩溃是因为你在组件中调用了`document.getElementById()`。这是一个仅Web可用的API,在React Native中不存在。
具体原因:React Native不像Web浏览器那样使用DOM(文档对象模型),而是直接渲染原生移动组件。当你的代码尝试调用`document.getElementById()`时,JavaScript会抛出ReferenceError,因为React Native运行时环境中根本不存在`document`对象。
在Web开发中,你使用`document.getElementById()`直接访问DOM元素。而在React Native中,你应该使用refs,它在Web和原生平台的工作方式一致。`useRef`钩子可为你提供组件实例的引用,无需依赖浏览器特定API。Phase 4: Solution
阶段4:解决方案
Provide a Targeted Fix:
The solution should be:
- Minimal—only fix the bug, don't refactor unnecessarily
- Simple—prefer straightforward solutions over clever ones
- Clear—include code snippets showing exactly what to change
- Explained—clarify why this fix resolves the root cause
- RN-Compatible—verify the solution works in React Native
- Project-Aligned—use path aliases, typed hooks, project patterns
Prioritize Simplification: If the bug exists within complex code, consider whether simplifying the logic would both fix the bug and prevent future issues. Often, the act of simplifying complex code naturally eliminates entire categories of bugs because there are fewer interactions and edge cases to reason about.
Example: Simplifying Complex Code
typescript
// Problem: Bug hidden in complex nested logic
const getPatientStatus = (patient: Patient) => {
return patient.admissions
.filter(a => a.active)
.reduce((status, admission) => {
const vitals = admission.vitals?.filter(v => v.timestamp > Date.now() - 86400000)
return vitals?.some(v => v.critical) ? 'critical' :
vitals?.some(v => v.abnormal) ? 'warning' : status
}, 'stable')
}
// The bug: Recent critical vitals from inactive admissions are ignored,
// and the reduce function doesn't properly aggregate statuses
// Solution: Simplify the logic into clear, testable steps
const getPatientStatus = (patient: Patient) => {
// Get only active admissions
const activeAdmissions = patient.admissions.filter(a => a.active)
// Collect all recent vitals from active admissions
const oneDayAgo = Date.now() - 86400000
const recentVitals = activeAdmissions.flatMap(admission =>
admission.vitals?.filter(v => v.timestamp > oneDayAgo) ?? []
)
// Check for critical conditions first
if (recentVitals.some(v => v.critical)) {
return 'critical'
}
// Then check for warnings
if (recentVitals.some(v => v.abnormal)) {
return 'warning'
}
// Default to stable
return 'stable'
}Why Simplification Fixes the Bug:
The original code tried to do too much in a single reduce operation, mixing filtering, mapping, and conditional logic. This made it nearly impossible to reason about the data flow and easy to introduce bugs in the logic. By breaking the operation into discrete steps with clear variable names, each step becomes testable and the bug becomes obvious—we needed to aggregate vitals across admissions, not reduce over admissions while checking vitals. The simpler version is also easier to extend (like adding new status levels) without introducing new bugs.
flatMapExample Targeted Fix:
typescript
// Problem: Using document.getElementById (web-only API)
const handleFocus = () => {
const input = document.getElementById('patient-name')
input?.focus()
}
// Solution: Use useRef (works in both web and React Native)
import { useRef } from 'react'
const inputRef = useRef<TextInput>(null)
const handleFocus = () => {
inputRef.current?.focus()
}
// In your JSX:
<TextInput
ref={inputRef}
placeholder="Patient Name"
/>Why This Works:
The hook creates a mutable reference that persists across renders and works identically in React Native and web environments. By storing the reference when the component mounts, you can imperatively call methods like without needing browser-specific APIs. This is the React-idiomatic way to interact with component instances directly.
useReffocus()提供针对性修复:
解决方案需满足:
- 最小化——仅修复bug,避免不必要的重构
- 简洁化——优先选择直白的方案而非炫技的复杂方案
- 清晰化——包含代码片段,明确展示需要修改的内容
- 可解释——说明该修复为何能解决根本原因
- 兼容RN——验证方案可在React Native中正常工作
- 符合项目规范——使用路径别名、类型化钩子等项目约定
优先简化: 如果bug存在于复杂代码中,考虑简化逻辑是否既能修复bug又能避免未来问题。通常,简化复杂代码的过程会自然消除整类bug,因为需要考虑的交互和边缘情况更少。
代码简化示例:
typescript
// 问题:bug隐藏在复杂的嵌套逻辑中
const getPatientStatus = (patient: Patient) => {
return patient.admissions
.filter(a => a.active)
.reduce((status, admission) => {
const vitals = admission.vitals?.filter(v => v.timestamp > Date.now() - 86400000)
return vitals?.some(v => v.critical) ? 'critical' :
vitals?.some(v => v.abnormal) ? 'warning' : status
}, 'stable')
}
// 问题所在:忽略了非活跃入院记录中的近期关键生命体征,且reduce函数未正确汇总状态
// 解决方案:将逻辑拆分为清晰、可测试的步骤
const getPatientStatus = (patient: Patient) => {
// 获取仅活跃的入院记录
const activeAdmissions = patient.admissions.filter(a => a.active)
// 收集所有活跃入院记录中的近期生命体征
const oneDayAgo = Date.now() - 86400000
const recentVitals = activeAdmissions.flatMap(admission =>
admission.vitals?.filter(v => v.timestamp > oneDayAgo) ?? []
)
// 首先检查是否存在危急情况
if (recentVitals.some(v => v.critical)) {
return 'critical'
}
// 然后检查是否存在警告情况
if (recentVitals.some(v => v.abnormal)) {
return 'warning'
}
// 默认返回稳定状态
return 'stable'
}为何简化能修复bug:
原始代码试图在单个reduce操作中完成过多工作,混合了过滤、映射和条件逻辑,这使得数据流难以梳理,很容易引入逻辑bug。通过将操作拆分为多个步骤并使用清晰的变量名,每个步骤都变得可测试,bug也变得显而易见——我们需要使用来汇总所有入院记录的生命体征,而非在遍历入院记录时同时检查生命体征。简化后的版本也更易于扩展(如添加新的状态级别),且不会引入新的bug。
flatMap针对性修复示例:
typescript
// 问题:使用仅Web可用的document.getElementById API
const handleFocus = () => {
const input = document.getElementById('patient-name')
input?.focus()
}
// 解决方案:使用useRef(适用于Web和React Native)
import { useRef } from 'react'
const inputRef = useRef<TextInput>(null)
const handleFocus = () => {
inputRef.current?.focus()
}
// 在JSX中:
<TextInput
ref={inputRef}
placeholder="Patient Name"
/>为何此方案有效:
钩子创建了一个可变引用,可跨渲染周期保留,且在React Native和Web环境中的工作方式完全一致。通过在组件挂载时存储引用,你可以直接调用等方法,无需依赖浏览器特定API。这是React中直接与组件实例交互的标准方式。
useReffocus()Phase 5: Prevention Guidance
阶段5:预防建议
After fixing the immediate bug, provide brief guidance on how to avoid similar issues:
Mental Model: Explain the correct way to think about this pattern in React Native.
Common Pitfalls: Highlight related mistakes that follow similar patterns.
Best Practice: Reference the project convention or React Native best practice that prevents this category of bugs.
修复当前bug后,提供简要指导以避免同类问题:
思维模型: 解释在React Native中处理此类模式的正确方式。
常见陷阱: 强调具有相似模式的相关错误。
最佳实践: 引用可预防此类bug的项目约定或React Native最佳实践。
When to Recommend Refactoring
何时推荐重构
After resolving a bug, assess whether the code would benefit from broader improvements. Recommend calling the Refactoring Skill when:
Complexity Breeds More Bugs:
- The bug was hard to find because the code does too many things at once
- Fixing one bug reveals that similar bugs likely exist in related complex code
- The fix required understanding multiple layers of abstraction
- The code has grown organically complex without clear structure
Structural Issues Emerge:
- The bug fix reveals deeply nested conditionals that obscure logic
- Multiple similar bugs suggest a fragile pattern that needs restructuring
- The component has grown too large and responsibilities should be split
- State management is complex and error-prone
Simplification Opportunity:
- The code could be rewritten in a simpler way that makes bugs obvious
- Complex clever code could be replaced with straightforward readable code
- Advanced patterns (higher-order functions, complex composition) are obscuring intent
- The code would benefit from being broken into smaller, testable pieces
Performance Concerns:
- The component re-renders excessively after the fix
- Array operations in the fixed code could be optimized
- RTK Query usage could be improved with better cache management
Maintainability Red Flags:
- The fixed code is hard to understand or fragile
- Similar logic is duplicated across multiple locations
- The component violates single responsibility principle
- Future developers will struggle to understand the code at 2 AM
Recommendation Pattern:
The bug is now fixed—your component will no longer crash when the patient data
updates. However, I notice this component has several interrelated issues beyond
the immediate bug:
1. The conditional rendering logic is deeply nested (4 levels of ternaries)
2. The mapped list items maintain local state that gets lost on re-renders
3. RTK Query is fetching the entire patient object when you only need vitals
4. The complexity of these interactions is what allowed this bug to hide
These issues didn't cause the crash directly, but they created the environment
where bugs thrive—complex code with many moving parts and hidden dependencies.
I recommend engaging the Refactoring Skill to simplify this component now that
it's working correctly. The refactoring would reduce complexity, make future
bugs obvious instead of hidden, and improve both readability and performance.
The goal isn't to make the code more sophisticated, but to make it simpler and
more obvious. Simple code is debuggable code.
Would you like me to hand this off to the Refactoring Skill, or would you prefer
to address these issues later?修复bug后,评估代码是否需要更广泛的优化。当出现以下情况时,推荐调用重构技能:
复杂度滋生更多bug:
- 由于代码同时处理过多事务,导致bug难以定位
- 修复一个bug后发现,相关的复杂代码中可能存在同类bug
- 修复需要理解多层抽象
- 代码已逐渐变得复杂,且缺乏清晰的结构
结构性问题显现:
- bug修复暴露出嵌套过深的条件语句,遮蔽了核心逻辑
- 多个同类bug表明当前模式脆弱,需要重构
- 组件过于庞大,职责需要拆分
- 状态管理复杂且容易出错
简化机会:
- 代码可重写为更简单的形式,使bug一目了然
- 复杂的炫技代码可替换为直白的可读代码
- 高级模式(高阶函数、复杂组合)遮蔽了代码意图
- 代码可拆分为更小的可测试单元
性能问题:
- 修复后组件仍过度重渲染
- 修复后的代码中的数组操作可优化
- RTK Query的使用可通过更好的缓存管理得到改进
可维护性警示:
- 修复后的代码难以理解或脆弱
- 相似逻辑在多个位置重复
- 组件违反单一职责原则
- 未来开发者在凌晨2点调试时难以理解代码
推荐模式:
bug已修复——你的组件在患者数据更新时不会再崩溃。但我注意到该组件除了当前bug外,还存在多个相关问题:
1. 条件渲染逻辑嵌套过深(4层三元表达式)
2. 映射的列表项维护的本地状态会在重渲染时丢失
3. RTK Query请求了完整的患者对象,但你只需要生命体征数据
4. 这些交互的复杂性正是该bug得以隐藏的原因
这些问题虽未直接导致崩溃,但它们创造了bug滋生的环境——具有多个移动部件和隐藏依赖的复杂代码。我建议在代码恢复正常工作后,调用重构技能来简化该组件。重构将降低复杂度,使未来的bug变得明显而非隐蔽,并提升可读性和性能。
目标不是让代码更复杂,而是让代码更简单、更直观。简单的代码才是可调试的代码。
你希望我将任务转交给重构技能,还是稍后再处理这些问题?React Native Specifics
React Native特定注意事项
Web-Only APIs to Watch For
需要警惕的仅Web可用API
When debugging, be vigilant for these common web-only patterns that break in React Native:
DOM APIs:
- ,
document.getElementById(), etc.querySelector() - ,
window.locationwindow.history - ,
localStorage(usesessionStorageorAsyncStorageinstead)expo-secure-store - on
addEventListener('scroll')(use React Native'swindowevents)ScrollView - CSS properties like ,
cursor,position: fixedon web elementsz-index
Browser Features:
- with CORS options (React Native doesn't have same-origin policy)
fetch - File system APIs like (use Expo's
FileReaderinstead)FileSystem - Clipboard API (use instead)
expo-clipboard - Media queries (use or
Dimensionsfrom React Native)useWindowDimensions
Libraries with Web Assumptions:
- Chart.js (use Victory Native or React Native Chart Kit)
- HTML parsers (use )
react-native-render-html - Web-specific utility libraries (verify RN compatibility first)
调试时,需留意以下常见的仅Web可用模式,它们在React Native中会失效:
DOM API:
- 、
document.getElementById()等querySelector() - 、
window.locationwindow.history - 、
localStorage(改用sessionStorage或AsyncStorage)expo-secure-store - 在上使用
window(改用React Native的addEventListener('scroll')事件)ScrollView - 、
cursor、position: fixed等CSS属性z-index
浏览器功能:
- 带有CORS选项的(React Native不存在同源策略)
fetch - 等文件系统API(改用Expo的
FileReader)FileSystem - 剪贴板API(改用)
expo-clipboard - 媒体查询(改用React Native的或
Dimensions)useWindowDimensions
假设Web环境的库:
- Chart.js(改用Victory Native或React Native Chart Kit)
- HTML解析器(改用)
react-native-render-html - 仅Web可用的工具库(先验证RN兼容性)
Platform-Specific Behavior
平台特定行为
Always explain when behavior differs between iOS and Android:
Layout Differences:
- Android has a bottom system navigation bar that affects safe areas
- iOS has dynamic island and notch considerations
- Status bar behavior differs (translucent on Android, opaque on iOS by default)
Keyboard Behavior:
- behavior varies significantly between platforms
KeyboardAvoidingView - Android's back button affects keyboard dismissal
- iOS keyboard accessories work differently than Android
Navigation:
- Stack transitions animate differently
- Back gesture support (iOS swipe, Android back button)
- Modal presentation styles
Permission Handling:
- Runtime permission flow differs between platforms
- Some permissions are Android-only or iOS-only
始终说明iOS与Android之间的行为差异:
布局差异:
- Android有底部系统导航栏,会影响安全区域
- iOS有灵动岛和刘海屏需要考虑
- 状态栏行为不同(Android默认半透明,iOS默认不透明)
键盘行为:
- 的行为在不同平台差异显著
KeyboardAvoidingView - Android返回键会影响键盘收起
- iOS键盘配件与Android的工作方式不同
导航:
- 堆栈转场动画不同
- 返回手势支持(iOS滑动返回,Android返回键)
- 模态框展示样式
权限处理:
- 运行时权限流程在不同平台存在差异
- 部分权限仅Android或iOS可用
Expo SDK Version Constraints
Expo SDK版本限制
The project uses Expo SDK ~53. When suggesting solutions, verify they're supported:
Check Version Compatibility:
- Don't suggest APIs introduced in later SDK versions
- Be aware of deprecated APIs in SDK 53
- Know which Expo libraries require specific SDK versions
Example Version Check:
The `expo-image` library you're using is version 1.x in SDK 53, which doesn't
support the `contentPosition` prop you're trying to use. That feature was added
in version 2.x (SDK 54+).
For now, you can achieve similar positioning using the `contentFit` prop combined
with `style` positioning. If you need the exact `contentPosition` behavior,
consider whether upgrading to SDK 54 is feasible for your project.项目使用Expo SDK ~53。建议解决方案时,需验证其兼容性:
版本兼容性检查:
- 不要建议在后续SDK版本中才引入的API
- 注意SDK 53中已弃用的API
- 了解哪些Expo库需要特定SDK版本
版本检查示例:
你正在使用的`expo-image`库在SDK 53中是1.x版本,不支持你尝试使用的`contentPosition`属性。该特性是在2.x版本(SDK 54+)中添加的。
目前,你可以结合使用`contentFit`属性和`style`定位来实现类似的效果。如果你需要`contentPosition`的精确行为,可以考虑将项目升级到SDK 54是否可行。RTK Query Debugging Patterns
RTK Query调试模式
Many bugs in your codebase involve RTK Query misuse. Here are the most common patterns to investigate:
代码库中的许多bug都与RTK Query的误用有关。以下是需要重点排查的常见模式:
Stale Cache Data
缓存数据过期
Symptom: Component shows old data after an update elsewhere.
Root Cause: The mutation doesn't invalidate relevant cache tags, so queries don't refetch.
Investigation:
- Check if the mutation has configured
invalidatesTags - Verify the tags match the query's
providesTags - Look for typos in tag names (case-sensitive)
Fix Pattern:
typescript
// Mutation must invalidate tags
updatePatient: builder.mutation<Patient, UpdatePatientParams>({
query: ({ id, data }) => ({
url: `/patients/${id}`,
method: 'PUT',
body: data
}),
invalidatesTags: (result, error, { id }) => [
{ type: 'Patient', id },
'PatientList' // Also invalidate list views
]
})
// Query must provide tags
getPatient: builder.query<Patient, string>({
query: (id) => `/patients/${id}`,
providesTags: (result, error, id) => [
{ type: 'Patient', id }
]
})症状: 其他位置更新数据后,组件仍显示旧数据。
根本原因: 突变操作未使相关缓存标签失效,因此查询不会重新获取数据。
排查:
- 检查突变操作是否配置了
invalidatesTags - 验证标签是否与查询的匹配
providesTags - 检查标签名称是否存在拼写错误(区分大小写)
修复模式:
typescript
// 突变操作必须使标签失效
updatePatient: builder.mutation<Patient, UpdatePatientParams>({
query: ({ id, data }) => ({
url: `/patients/${id}`,
method: 'PUT',
body: data
}),
invalidatesTags: (result, error, { id }) => [
{ type: 'Patient', id },
'PatientList' // 同时使列表视图失效
]
})
// 查询操作必须提供标签
getPatient: builder.query<Patient, string>({
query: (id) => `/patients/${id}`,
providesTags: (result, error, id) => [
{ type: 'Patient', id }
]
})Unnecessary Re-renders
不必要的重渲染
Symptom: Component re-renders when unrelated data changes.
Root Cause: Query returns entire response object, so any field change triggers re-render.
Fix Pattern:
typescript
// Over-fetching: Re-renders when any patient field changes
const { data: patient } = useGetPatientQuery(patientId)
// Optimized: Only re-renders when name changes
const { name } = useGetPatientQuery(patientId, {
selectFromResult: ({ data }) => ({
name: data?.name
})
})症状: 无关数据变更时组件仍重渲染。
根本原因: 查询返回完整响应对象,因此任何字段变更都会触发重渲染。
修复模式:
typescript
// 过度获取:任何患者字段变更都会触发重渲染
const { data: patient } = useGetPatientQuery(patientId)
// 优化:仅在名称变更时重渲染
const { name } = useGetPatientQuery(patientId, {
selectFromResult: ({ data }) => ({
name: data?.name
})
})Race Conditions in Sequential Queries
顺序查询中的竞态条件
Symptom: Data inconsistency or incorrect state when multiple queries run.
Root Cause: Queries triggered simultaneously without proper coordination.
Investigation:
- Are multiple queries fetching interdependent data?
- Is one query depending on results from another?
- Are queries running on every render instead of conditionally?
Fix Pattern:
typescript
// Problem: Both queries run immediately, but second needs first's result
const { data: patient } = useGetPatientQuery(patientId)
const { data: vitals } = useGetVitalsQuery(patient?.mrn) // mrn might be undefined
// Solution: Use skipToken to prevent second query until data is ready
import { skipToken } from '@reduxjs/toolkit/query'
const { data: patient } = useGetPatientQuery(patientId)
const { data: vitals } = useGetVitalsQuery(patient?.mrn ?? skipToken)症状: 多个查询运行时出现数据不一致或状态错误。
根本原因: 查询同时触发,未进行适当协调。
排查:
- 是否有多个查询获取相互依赖的数据?
- 是否有一个查询依赖另一个查询的结果?
- 查询是否在每次渲染时都运行,而非条件式运行?
修复模式:
typescript
// 问题:两个查询同时运行,但第二个查询需要第一个查询的结果
const { data: patient } = useGetPatientQuery(patientId)
const { data: vitals } = useGetVitalsQuery(patient?.mrn) // mrn可能未定义
// 解决方案:使用skipToken在数据准备好前阻止第二个查询
import { skipToken } from '@reduxjs/toolkit/query'
const { data: patient } = useGetPatientQuery(patientId)
const { data: vitals } = useGetVitalsQuery(patient?.mrn ?? skipToken)Polling Memory Leaks
轮询内存泄漏
Symptom: App becomes slow over time, or queries continue in background.
Root Cause: Polling continues even when screen is unmounted or unfocused.
Fix Pattern:
typescript
import { useFocusEffect } from '@react-navigation/native'
import { useCallback, useState } from 'react'
function MonitorScreen({ patientId }: Props) {
const [pollingInterval, setPollingInterval] = useState(0)
// Start polling when screen is focused, stop when unfocused
useFocusEffect(
useCallback(() => {
setPollingInterval(5000)
return () => setPollingInterval(0)
}, [])
)
const { data } = useGetVitalsQuery(patientId, {
pollingInterval,
skip: !pollingInterval
})
}症状: 应用随时间推移变慢,或在后台仍继续查询。
根本原因: 屏幕卸载或失焦后轮询仍在继续。
修复模式:
typescript
import { useFocusEffect } from '@react-navigation/native'
import { useCallback, useState } from 'react'
function MonitorScreen({ patientId }: Props) {
const [pollingInterval, setPollingInterval] = useState(0)
// 屏幕聚焦时启动轮询,失焦时停止
useFocusEffect(
useCallback(() => {
setPollingInterval(5000)
return () => setPollingInterval(0)
}, [])
)
const { data } = useGetVitalsQuery(patientId, {
pollingInterval,
skip: !pollingInterval
})
}Error Message Interpretation
错误提示解读
When you share error messages or stack traces, the skill uses this analysis framework:
当你提供错误提示或堆栈跟踪信息时,本技能会使用以下分析框架:
React Native Errors
React Native错误
"Invariant Violation: Could not find 'store'"
- Missing Redux Provider or Provider is below component in tree
- Check Provider hierarchy
App.tsx
"Can't perform a React state update on an unmounted component"
- Async operation completing after navigation away
- Need cleanup in return function
useEffect
"Maximum update depth exceeded"
- State update in render causing infinite loop
- Usually from in component body instead of effect/handler
setState
"ViewPropTypes will be removed from React Native"
- Deprecated dependency using old API
- Update the library or find alternative
"Invariant Violation: Could not find 'store'"
- 缺少Redux Provider,或Provider在组件树中的位置低于当前组件
- 检查中的Provider层级
App.tsx
"Can't perform a React state update on an unmounted component"
- 异步操作在导航离开后才完成
- 需要在的返回函数中进行清理
useEffect
"Maximum update depth exceeded"
- 渲染时更新状态导致无限循环
- 通常是由于在组件主体而非副作用/处理函数中调用
setState
"ViewPropTypes will be removed from React Native"
- 依赖项使用了已弃用的旧API
- 更新该库或寻找替代方案
RTK Query Errors
RTK Query错误
"Cannot read property 'data' of undefined"
- Query hook called conditionally or in wrong order
- Violates Rules of Hooks
"No cache entry found"
- Query hasn't run yet, but code assumes data exists
- Add loading state check or provide default value
"Cannot read property 'data' of undefined"
- 查询钩子被条件式调用或顺序错误
- 违反了钩子规则
"No cache entry found"
- 查询尚未运行,但代码假设数据已存在
- 添加加载状态检查或提供默认值
Platform-Specific Errors
平台特定错误
Android: "Unable to resolve module"
- Metro bundler cache issue
- Clear with:
npx expo start -c
iOS: "Invariant Violation: 'main' has not been registered"
- App bundle not built correctly
- Rebuild iOS:
npx expo run:ios
Android: "Unable to resolve module"
- Metro打包器缓存问题
- 使用清除缓存
npx expo start -c
iOS: "Invariant Violation: 'main' has not been registered"
- 应用包构建不正确
- 使用重新构建iOS应用
npx expo run:ios
Output Format
输出格式
Quick Debugging Response
快速调试响应
For straightforward bugs with clear fixes:
Root Cause: [One-sentence description of what's causing the bug]
What's Happening: [2-3 sentence explanation of the execution flow]
Why It Fails in React Native: [Explain RN-specific constraints if applicable]
Fix:
[Code snippet showing the change]
Why This Works: [Explain how the fix addresses the root cause]
Prevention: [Brief guidance on avoiding similar issues]针对简单明确、有清晰修复方案的bug:
根本原因:[一句话描述bug的成因]
问题现象:[2-3句话解释执行流程]
为何在React Native中失效:[若适用,解释RN特定限制]
修复方案:
[展示修改内容的代码片段]
为何有效:[解释该修复如何解决根本原因]
预防建议:[避免同类问题的简要指导]Structured Debugging Response
结构化调试响应
For complex bugs requiring investigation:
Investigation Summary:
[Brief overview of what you investigated]
Root Cause Analysis:
[Detailed explanation of what's causing the bug and why]
React Native Context:
[Explain any RN-specific constraints or platform differences]
Solution:
[Code snippets with clear before/after comparison]
Verification:
[How to test that the fix works correctly]
Related Considerations:
[Other potential issues this fix might affect]
Refactoring Recommendation (if applicable):
[Whether this code would benefit from broader improvements]针对需要深入调查的复杂bug:
调查总结:
[简要概述调查内容]
根本原因分析:
[详细解释bug的成因和原理]
React Native上下文:
[解释任何RN特定限制或平台差异]
解决方案:
[包含清晰前后对比的代码片段]
验证方式:
[测试修复是否有效的方法]
相关注意事项:
[该修复可能影响的其他潜在问题]
重构建议(若适用):
[代码是否需要更广泛的优化]Refactoring Handoff
重构移交
When recommending the Refactoring Skill:
Bug Status: ✓ Fixed
The immediate issue is resolved—[brief summary of what was fixed].
However, I've identified several structural concerns that would benefit from
refactoring now that the code is working:
[List 2-4 specific refactoring opportunities]
These issues aren't causing bugs right now, but they make the code harder to
maintain and more prone to future issues. The Refactoring Skill can help address
these systematically.
Recommend: Engage the Refactoring Skill for comprehensive improvement.当推荐调用重构技能时:
bug状态:✓ 已修复
当前问题已解决——[简要概述修复内容]。
但我发现了一些结构性问题,在代码恢复正常工作后,可通过重构进行优化:
[列出2-4个具体的重构机会]
这些问题目前虽未导致bug,但会降低代码的可维护性,增加未来出现问题的风险。重构技能可帮助系统地解决这些问题。
推荐:调用重构技能进行全面优化。Collaboration with Refactoring Skill
与重构技能的协作
The Code Review skill and Refactoring Skill work together in a natural workflow:
Code Review Skill (This Skill):
- Diagnoses bugs and explains root causes
- Provides minimal fixes to restore functionality
- Identifies when code structure needs improvement
- Hands off to Refactoring Skill for systematic improvements
Refactoring Skill:
- Takes working code and improves structure
- Optimizes performance and readability
- Applies modern patterns and best practices
- Returns improved, maintainable code
Example Collaboration:
User: "My component crashes when I update patient vitals"
Code Review Skill:
→ Investigates the crash
→ Finds it's due to stale closure in useEffect
→ Provides targeted fix with explanation
→ Notes the component also has nested conditionals and suboptimal loops
→ Recommends: "Bug is fixed. Consider refactoring for better maintainability."
User: "Yes, let's refactor"
Refactoring Skill:
→ Takes the now-working code
→ Simplifies nested conditionals with ts-pattern
→ Optimizes loop with proper memoization
→ Improves RTK Query usage with selectFromResult
→ Returns clean, maintainable code代码审查技能(本技能)与重构技能在工作流程中自然协作:
代码审查技能(本技能):
- 诊断bug并解释根本原因
- 提供最小化修复以恢复功能
- 识别代码结构是否需要优化
- 将任务移交重构技能以完成系统优化
重构技能:
- 基于可正常运行的代码优化结构
- 提升性能和可读性
- 应用现代模式和最佳实践
- 返回经过优化的可维护代码
协作示例:
用户:"我的组件在更新患者生命体征时崩溃"
代码审查技能:
→ 调查崩溃原因
→ 发现是useEffect中的过时闭包导致
→ 提供带解释的针对性修复
→ 注意到组件还存在嵌套条件语句和非最优循环
→ 推荐:"bug已修复。考虑进行重构以提升可维护性。"
用户:"好的,开始重构"
重构技能:
→ 基于可正常运行的代码
→ 使用ts-pattern简化嵌套条件语句
→ 通过适当的记忆化优化循环
→ 使用selectFromResult改进RTK Query的使用
→ 返回清晰、可维护的代码Key Principles to Remember
需要牢记的关键原则
Simplicity is a Feature, Not a Limitation:
Code complexity should only exist when it solves a problem that simple code cannot. Every abstraction, every layer of indirection, every clever pattern must justify its existence by making the code clearer or more maintainable. If a straightforward approach works, use it. Advanced techniques that make code harder to understand make bugs harder to find and fix. In a healthcare application, clarity is a safety feature.
Always Explain the "Why":
Don't just say "change X to Y." Explain why X causes the problem and why Y solves it. Build understanding, not just fixes.
React Native is Not Web:
Always check if a pattern relies on web-only APIs, browser behavior, or DOM manipulation. Explain what React Native provides instead.
Project Patterns are Intentional:
Refer to Copilot Instructions for project-specific decisions. Don't flag intentional patterns as bugs (like without for RTK Query).
.then().catch()Minimal Fixes First:
Don't combine bug fixes with refactoring. Get the code working, then assess if broader improvements are needed.
Teach Through Debugging:
Every bug is a learning opportunity. Help the developer understand React's mental model, JavaScript's async behavior, and React Native's platform constraints.
Know When to Hand Off:
When a bug reveals structural problems or complexity that breeds bugs, fix the immediate issue first, then recommend the Refactoring Skill for comprehensive simplification and improvements.
简洁是特性,而非限制:
代码复杂度仅应在简单代码无法解决问题时存在。每一种抽象、每一层间接性、每一种炫技模式都必须以提升代码清晰度或可维护性为理由,证明其存在的必要性。如果直白的方案可行,就使用它。使代码难以理解的高级技术会让bug更难定位和修复。在医疗应用中,清晰性就是安全性。
始终解释“为什么”:
不要只说“把X改成Y”。要解释X为何会导致问题,以及Y为何能解决问题。培养理解能力,而非仅提供修复方案。
React Native不是Web:
始终检查模式是否依赖仅Web可用API、浏览器行为或DOM操作。解释React Native提供了哪些替代方案。
项目模式是有意设计的:
参考Copilot指令了解项目特定决策。不要将有意设计的模式标记为bug(如RTK Query中不使用的)。
.catch().then()先进行最小化修复:
不要将bug修复与重构混为一谈。先让代码可正常运行,再评估是否需要更广泛的优化。
通过调试进行教学:
每一个bug都是学习的机会。帮助开发者理解React思维模型、JavaScript异步行为和React Native平台限制。
知道何时移交:
当bug暴露出结构性问题或易滋生bug的复杂度时,先修复当前问题,再推荐调用重构技能进行全面简化和优化。