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

递归async/await导致React应用崩溃问题求助

搞定你的React排序应用问题!

嘿,我帮你找到问题根源啦!你的归并排序崩溃+React渲染报错,其实是两个核心问题在搞鬼,咱们一步步拆解解决:

1. 递归调用async函数没加await,导致参数全是Promise

你的mergeSort是async函数,递归调用this.mergeSort(left)和this.mergeSort(right)的时候,返回的都是Promise对象,但你直接把这俩Promise传给了merge函数——可merge要的是实实在在的数组啊!这不仅会让merge里的left.length这类操作直接出错,还会让整个mergeSort的返回值变成嵌套的Promise,最后搞砸整个流程。

把mergeSort改成这样就好:

async mergeSort(arr) {
  if(arr.length < 2) {
    return arr;
  }
  const m = Math.floor(arr.length / 2);
  let left = arr.slice(0, m);
  let right = arr.slice(m);
  await this.sleep();
  // 递归调用必须加await,拿到真正排序后的数组
  left = await this.mergeSort(left);
  right = await this.mergeSort(right);
  // merge也是async函数,同样要await它的结果
  return await this.merge(left, right);
}

2. 把Promise直接塞给了React State,导致渲染报错

那个Objects are not valid as a React child的错误,说明你肯定在某个地方(比如触发排序的onSortBtn函数里)把mergeSort返回的Promise直接赋值给了state.hatArray。React可没法渲染Promise对象,这不报错才怪!

两种解决思路:

思路一:等排序完成再更新UI(适合只看最终结果的场景)

如果不需要实时看每一步排序动画,就等整个排序完成后再把结果赋值给state:

async onSortBtn() {
  this.setState({ sorting: true });
  // 先复制当前数组,避免直接修改原state
  const sortedArray = await this.mergeSort([...this.state.hatArray]);
  // 排序完成后更新state
  this.setState({
    hatArray: sortedArray,
    sorting: false,
    sorted: true,
    endTime: Date.now()
  });
}

思路二:实时更新每一步排序状态(要做动画就得这么搞)

如果想让用户看到每一步排序的过程,就得在merge函数里每操作一次就更新state,而不是等最后返回数组。修改后的merge函数如下:

async merge(left, right) {
  let result = [];
  // 封装一个更新state的函数,用函数式更新避免异步问题
  const updateHatArray = (newArr) => {
    this.setState(prevState => ({
      hatArray: [...newArr]
    }));
  };

  while(left.length && right.length) {
    if(left[0].props.number <= right[0].props.number) {
      result.push(left.shift());
    } else {
      result.push(right.shift());
    }
    // 更新当前的数组状态
    updateHatArray(result.concat(left, right));
    await this.sleep();
  }

  while(left.length) {
    result.push(left.shift());
    updateHatArray(result.concat(left, right));
    await this.sleep();
  }

  while(right.length) {
    result.push(right.shift());
    updateHatArray(result.concat(left, right));
    await this.sleep();
  }

  return result;
}

这样每一步merge操作后,UI都会实时更新,用户就能看到排序的动画效果啦!

最后提个小提醒

排序开始的时候,记得把sorting设为true,禁用排序按钮,别让用户重复触发排序,不然会打乱整个流程哦~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:01:12