You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native调用setState更新分类列表时应用冻结问题排查求助

问题根因

你的应用冻结是loadViews方法中存在死循环导致的:

  • 非平板设备场景下,isTablet为false的else分支,仅执行了viewRows.push(this.renderEvenRow(i, categories[i])),没有给循环变量i做自增操作,i永远保持初始值0,只要categories数组长度大于0就会无限循环,卡死JS线程。
  • 平板设备的odd行分支也存在遗漏:当i == categories.length - 1(只剩最后一个分类)的判断分支中,同样没有执行i += 1,也会触发死循环。

你注释setState时,state中categories是空数组,循环不会执行,所以不会触发卡死问题,控制台也能正常打印接口返回的内容。

修复方案

修改loadViews方法的两处逻辑即可:

loadViews() {
  let i = 0;
  let rowType = "odd";
  let viewRows = [];

  const { categories } = this.state;

  console.log(categories.length);
  while (i < categories.length) {
    console.log("//", i);
    if (isTablet) {
      switch (rowType) {
        case "odd":
          if (i == categories.length - 1) {
            viewRows.push(this.renderEvenRow(i, categories[i]));
            // 新增:最后一项处理完后i自增
            i += 1;
          } else {
            viewRows.push(
              this.renderOddRow(i, categories[i], categories[i + 1])
            );
            rowType = "even";
            i += 2;
          }
          break;
        case "even":
          viewRows.push(this.renderEvenRow(i, categories[i]));
          rowType = "odd";
          i += 1;
          break;
        default:
          break;
      }
    } else {
      viewRows.push(this.renderEvenRow(i, categories[i]));
      // 新增:非平板场景每处理一项i自增
      i += 1;
    }
  }

  return viewRows;
}
额外优化建议
  • 可以将S3图片地址的获取逻辑做并发处理,减少接口等待时间:把for..of的串行请求改成Promise.all并行请求所有图片地址。
  • 建议替换为React Native官方的FlatList组件实现列表渲染,替代手动拼接渲染数组,性能更好也更不容易出现循环逻辑错误。

内容的提问来源于stack exchange,提问作者Malcolm S

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 22:30:02