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

React函数组件中特定state变化时如何阻止答案重新随机排序的重渲染

解决方案

问题根本原因

你把随机排序逻辑直接写在了JSX渲染代码中,每次组件触发重渲染(包括选中答案更新selectedAnswerId、selectedAnswer两个state的场景),都会重新执行一次随机排序逻辑,导致选项顺序被再次打乱。

修复方案

方案1:使用useMemo缓存打乱后的选项(推荐)

仅在切换题目时重新随机排序选项,选中答案等其他场景触发重渲染时直接复用缓存的排序结果:
首先在组件内定义缓存变量:

import { useMemo } from 'react'

// 仅当currentQuestion变化时,才重新生成打乱后的选项
const shuffledOptions = useMemo(() => {
  return questions[currentQuestion].options
    .slice(0, questions[currentQuestion].options.length - 1)
    .sort(() => Math.random() - 0.5)
}, [currentQuestion])

然后把原JSX中的排序逻辑替换为直接遍历shuffledOptions,同时注意把列表key从index替换为answer.id,避免React Diff时出现组件复用异常:

{shuffledOptions.map((answer) => (
  <TouchableOpacity
    onPress={selectedAnswerHandler.bind(
      this,
      answer.id,
      answer.answerText
    )}
    key={answer.id}
  >
    {/* 原有内部View、Text样式逻辑保持不变 */}
    <View
      style={
        selectedAnwserId === answer.id
          ? styles.selectedAnswerTab
          : styles.answerTab
      }
    >
      <Text
        style={
          selectedAnwserId === answer.id
            ? [styles.answerText, { color: color.secondaryColor }]
            : styles.answerText
        }
      >
        {answer.answerText}
      </Text>
    </View>
  </TouchableOpacity>
))}

方案2:将打乱后的选项存入state

和useMemo效果一致,适合需要后续手动修改选项排序的场景:

import { useState, useEffect } from 'react'

const [shuffledOptions, setShuffledOptions] = useState([])

// 切换题目时重新打乱选项
useEffect(() => {
  const newOptions = questions[currentQuestion].options
    .slice(0, questions[currentQuestion].options.length - 1)
    .sort(() => Math.random() - 0.5)
  setShuffledOptions(newOptions)
}, [currentQuestion])

渲染逻辑和方案1完全一致,直接遍历shuffledOptions即可。

附加优化建议

你当前使用的sort(() => Math.random() - 0.5)不是公平的洗牌算法,不同位置选项的排序概率会有偏差,如果对排序公平性要求较高,可以替换为Fisher-Yates洗牌算法:

const shuffleArray = (array) => {
  const newArr = [...array]
  for (let i = newArr.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    [newArr[i], newArr[j]] = [newArr[j], newArr[i]]
  }
  return newArr
}

使用时把排序部分替换为shuffleArray(待排序数组)即可。

内容的提问来源于stack exchange,提问作者Wahas Ali Mughal

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 17:45:04