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

React Native中从数组取三个不重复随机单词的代码问题排查

问题:从数组获取三个不重复随机单词时过滤失效,重复单词仍出现

想要编写一个从数组中获取三个不重复随机单词的函数,参考相关内容实现数组过滤,但过滤功能未生效。实现代码如下:

takeThreeWords=()=>{
    for(i=0;i<3;i++){
    rand =(max, min=0)=> Math.floor(Math.random()*max-min)
    randomWord=()=> this.state.wordsBank[rand(this.state.wordsBank.length)]
    let aRandomWord = randomWord()
    
    this.setState(prevState=>({
      wordsToUse:[...prevState.wordsToUse, aRandomWord],
      wordsBank: prevState.wordsBank.filter(word=>word!== aRandomWord)

    }))
}

原本期望通过过滤确保wordsBank中的单词不会被重复选取,但实际运行时wordsToUse仍会出现重复单词,请问忽略了什么问题?


问题分析与解决方案

核心问题:setState的异步特性导致状态更新不同步

React的setState是异步操作,循环中连续调用setState时,每次循环里的prevState并不会立即反映前一次setState的更新结果。也就是说,三次循环里的prevState.wordsBank其实都是初始的数组状态,过滤操作并没有基于已经移除过元素的数组,自然无法避免重复选取。

其他次要问题

  • 随机数函数计算错误:rand函数的公式逻辑有误,正确的区间随机整数计算应该是Math.floor(Math.random() * (max - min)) + min,原写法可能会产生负数索引,导致取到错误的元素甚至undefined。
  • 变量未声明导致全局污染:rand和randomWord没有用let/const声明,会变成全局变量,属于不良编码习惯。
  • 函数定义放在循环内冗余:每次循环都重新定义rand和randomWord函数,完全没必要,应该提到循环外部。

修正后的代码实现

推荐先在内存中完成数组的随机选取和过滤,再一次性更新状态,避免异步更新带来的问题:

takeThreeWords = () => {
  // 复制原数组,避免直接修改state
  const remainingWords = [...this.state.wordsBank];
  const selectedWords = [];

  // 定义随机数生成函数,放在循环外
  const getRandomIndex = (max, min = 0) => {
    return Math.floor(Math.random() * (max - min)) + min;
  };

  for (let i = 0; i < 3; i++) {
    if (remainingWords.length === 0) break; // 防止数组元素不足时出错
    const randomIndex = getRandomIndex(remainingWords.length);
    const selectedWord = remainingWords.splice(randomIndex, 1)[0];
    selectedWords.push(selectedWord);
  }

  // 一次性更新状态
  this.setState({
    wordsToUse: [...this.state.wordsToUse, ...selectedWords],
    wordsBank: remainingWords
  });
};

代码说明

  1. 先复制wordsBank到内存数组remainingWords,后续操作都基于这个副本,确保每次选取都是从剩余元素中进行。
  2. 使用splice方法直接从remainingWords中移除选中的元素,保证不会重复选取。
  3. 最后一次性调用setState更新状态,避免异步更新的冲突。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 13:55:20