# 故障排查指南

Doubao Apps SDK 开发中常见问题的诊断和解决方案。 迭代过程中的新问题建议随时添加到该文档，方便团队内共享

---

## 🔍 问题诊断流程

### 系统化排查步骤

1. **复现问题** - 确定问题的触发条件
2. **查看日志** - 检查控制台错误信息
3. **隔离问题** - 缩小问题范围
4. **查找文档** - 搜索相关文档和示例
5. **尝试方案** - 逐一测试可能的解决方案

---

## 🐛 常见错误类型

### 1. 组件渲染错误

#### 问题：页面白屏或组件不显示

**症状**：
```
页面显示空白，控制台无错误
或者提示：Cannot read property 'xxx' of undefined
```

**可能原因**：
- 数据未加载完成就尝试渲染
- 必需的 props 未传递
- 条件渲染逻辑错误

**解决方案**：

```tsx
// ❌ 错误写法
function UserProfile({ user }: Props) {
  return (
    <view>
      <text>{user.name}</text>  {/* user 可能为 null */}
    </view>
  );
}

// ✅ 正确写法 - 添加安全检查
function UserProfile({ user }: Props) {
  if (!user) {
    return <LoadingView />;
  }

  return (
    <view>
      <text>{user.name}</text>
    </view>
  );
}

// ✅ 或使用可选链
function UserProfile({ user }: Props) {
  return (
    <view>
      <text>{user?.name || '未知用户'}</text>
    </view>
  );
}
```

#### 问题：组件频繁重新渲染

**症状**：
```
控制台大量渲染日志
页面卡顿，性能下降
```

**诊断方法**：

```tsx
// 添加渲染追踪
function MyComponent({ data }: Props) {
  const renderCount = useRef(0);

  useEffect(() => {
    renderCount.current += 1;
    console.log(`Render count: ${renderCount.current}`);
  });

  return <view>{/* ... */}</view>;
}
```

**解决方案**：

```tsx
// ✅ 使用 useMemo 缓存计算
const processedData = useMemo(() => {
  return heavyComputation(data);
}, [data]);

// ✅ 使用 useCallback 稳定函数引用
const handleClick = useCallback(() => {
  console.log('clicked');
}, []);
```

### 2. 生命周期问题

#### 问题：useShow / onShow 未触发

**可能原因**：
- 没有正确定义生命周期方法
- 页面未正确注册
- 路由配置错误

**解决方案**：

```tsx
// ❌ 错误写法：普通局部函数不会注册 View 生命周期
export default function Page() {
  const onShow = () => console.log('show');
  return <view>...</view>;
}

// ✅ 正确写法
import { useHide, useShow } from '@doubao-dev/framework';

export default function Page() {
  useShow(() => console.log('Page shown'));
  useHide(() => console.log('Page hidden'));

  return <view>...</view>;
}
```

使用 `useShow` / `useHide` 时，在入口组件函数顶层调用对应 Hook。

#### 问题：内存泄漏 - 组件卸载后仍在更新状态

**症状**：
```
Warning: Can't perform a React state update on an unmounted component
```

**解决方案**：

```tsx
// ✅ 使用 cleanup 函数
function DataFetcher() {
  const [data, setData] = useState(null);

  useEffect(() => {
    let mounted = true;

    const fetchData = async () => {
      const result = await api.getData();
      if (mounted) {  // 检查组件是否仍挂载
        setData(result);
      }
    };

    fetchData();

    return () => {
      mounted = false;  // cleanup
    };
  }, []);

  return <view>{/* ... */}</view>;
}

// ✅ 清理定时器
useEffect(() => {
  const timer = setInterval(() => {
    console.log('tick');
  }, 1000);

  return () => {
    clearInterval(timer);  // cleanup
  };
}, []);
```

### 3. 样式问题

#### 问题：样式不生效

**可能原因**：
- 样式文件未导入
- 选择器权重不够
- Lynx 不支持的 CSS 属性
- rpx 单位使用错误

**解决方案**：

```tsx
// ✅ 确保导入样式文件
import './index.scss';  // 必须导入

export default function Page() {
  return <view className="page" />;
}
```

```scss
// ✅ 检查选择器
.my-component {
  padding: 32rpx;  // ✅ 使用 rpx
  color: #333;

  &__title {
    font-size: 36rpx;
  }
}

// ❌ 避免使用不支持的属性
.my-component {
  position: sticky;  // ❌ Lynx 可能不支持
  backdrop-filter: blur(10px);  // ❌ 不支持
}
```

### 4. 数据请求问题

#### 问题：接口调用失败

**症状**：
```
Network Error
Request failed with status 400/401/404/500
```

**诊断步骤**：

```tsx
// ✅ 添加详细的错误日志
import { request } from '@doubao-dev/framework/api';

async function fetchData() {
  try {
    const response = await request({
      url: 'https://api.example.com/data',
      method: 'GET'
    });

    console.log('Response status:', response.statusCode);
    console.log('Response headers:', response.header);

    if (response.statusCode >= 400) {
      console.error('Error response:', response.data);
      throw new Error(`HTTP ${response.statusCode}: ${JSON.stringify(response.data)}`);
    }

    return response.data;
  } catch (error) {
    console.error('Request error:', error);
    throw error;
  }
}
```



## 🔧 常见解决方案速查

### 快速修复方案

| 问题 | 快速解决方案 |
|-----|-------------|
| 组件不显示 | 检查数据加载和空值处理 |
| 样式不生效 | 确认导入样式文件 |
| 内存泄漏 | 添加 cleanup 函数 |
| 网络请求失败 | 检查 URL、参数和错误处理 |
| 类型错误 | 添加可选链或类型守卫 |
| 页面卡顿 | 使用虚拟列表和分页 |
| 图片加载慢 | 使用懒加载和合适尺寸 |
