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

如何在Redux切片的Reducer中重执行函数以确保随机选不同国家

解决Redux切片中随机选取重复国家的问题

问题分析

你当前的代码仅做了一次判断:如果随机选中的两个国家相同,就不会更新questionOption1和questionOption2,但后续的状态重置(如correctAnswer1等)依然会执行,导致界面可能显示旧选项,或出现两个相同国家的情况。

解决方案

通过循环逻辑确保生成两个不同的随机国家,以下是两种可靠实现方式:


方式一:do-while循环确保国家不同

先随机选中第一个国家,再循环选取第二个国家,直到它与第一个国家不同:

import { createSlice } from "@reduxjs/toolkit";
import { data } from "../data/countries";

const initialState = {
  countries: data,
  questionOption1: {
    image: "",
    title: "",
    area: 0,
  },
  questionOption2: {
    image: "",
    title: "",
    area: 0,
  },
  correctAnswer1: true,
  correctAnswer2: true,
  correctAnswer1Tick: 0,
  correctAnswer2Tick: 0,
  total: 0,
};

const countriesSlice = createSlice({
  name: "countries",
  initialState,
  reducers: {
    setQuestion1: (state) => {
      // 随机选取第一个国家
      let random1 = state.countries[Math.floor(Math.random() * state.countries.length)];
      let random2;
      
      // 循环选取第二个国家,直到与第一个不同
      do {
        random2 = state.countries[Math.floor(Math.random() * state.countries.length)];
      } while (random1.title === random2.title); // 用title作为唯一标识,避免对象引用判断的潜在问题

      // 更新选项状态
      state.questionOption1 = {
        image: random1.image,
        title: random1.title,
        area: random1.area,
      };

      state.questionOption2 = {
        image: random2.image,
        title: random2.title,
        area: random2.area,
      };

      // 重置其他状态
      state.correctAnswer1 = true;
      state.correctAnswer2 = true;
      state.correctAnswer1Tick = 0;
      state.correctAnswer2Tick = 0;
    },
  },
});

export const countriesActions = countriesSlice.actions;
export default countriesSlice.reducer;

方式二:通过索引排除已选国家(效率更高)

先获取第一个国家的索引,再从剩余索引中随机选取第二个,避免重复判断:

import { createSlice } from "@reduxjs/toolkit";
import { data } from "../data/countries";

const initialState = {
  countries: data,
  questionOption1: {
    image: "",
    title: "",
    area: 0,
  },
  questionOption2: {
    image: "",
    title: "",
    area: 0,
  },
  correctAnswer1: true,
  correctAnswer2: true,
  correctAnswer1Tick: 0,
  correctAnswer2Tick: 0,
  total: 0,
};

const countriesSlice = createSlice({
  name: "countries",
  initialState,
  reducers: {
    setQuestion1: (state) => {
      const countryCount = state.countries.length;
      // 选取第一个国家的索引
      const index1 = Math.floor(Math.random() * countryCount);
      // 选取第二个国家的索引,确保不等于index1
      let index2;
      do {
        index2 = Math.floor(Math.random() * countryCount);
      } while (index2 === index1);

      const random1 = state.countries[index1];
      const random2 = state.countries[index2];

      // 更新选项状态
      state.questionOption1 = {
        image: random1.image,
        title: random1.title,
        area: random1.area,
      };

      state.questionOption2 = {
        image: random2.image,
        title: random2.title,
        area: random2.area,
      };

      // 重置其他状态
      state.correctAnswer1 = true;
      state.correctAnswer2 = true;
      state.correctAnswer1Tick = 0;
      state.correctAnswer2Tick = 0;
    },
  },
});

export const countriesActions = countriesSlice.actions;
export default countriesSlice.reducer;

关键说明

  • 用title(或其他唯一字段)代替对象引用比较:若data数组存在重复对象(概率极低),对象引用===判断可能失效,唯一标识字段更可靠。
  • 循环逻辑确保一定会生成两个不同的国家,不会出现跳过更新选项的情况。
  • 两种方式均可解决问题,方式二通过索引排除,在国家数量较多时效率略高。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 02:01:15