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

React onClick触发useState不更新状态且报updateChoice非函数错误如何解决?

React多选功能问题修复方案

问题根因

1. updateChoice不是函数报错原因

  • MultipleChoice组件中audioFiles.map的回调参数为(item, key),但传递给AudioButton时写的是file={file},file属于未定义变量,会触发组件渲染异常,导致props传递链断裂,updateChoice无法正常传递到子组件。
  • MultipleChoice组件直接返回数组格式的answerOption,没有用合法的JSX根节点包裹(比如Fragment或div),不符合React组件返回值规范,进一步触发渲染异常。
  • 列表渲染没有添加key属性,会触发React警告,极端情况下也会导致props传递异常。

2. 打印choice始终为初始值-1的原因

React的useState更新函数是异步批量执行的,调用setChoice后立刻打印choice,拿到的是当前函数闭包里的旧状态值,属于正常现象。如果要获取更新后的状态,需要通过useEffect监听choice变化后再读取。


修复后代码

QuestionPage组件

import { useState, useEffect } from 'react';

const QuestionPage = ({ audioFiles }) => {
  const [choice, setChoice] = useState(-1); // -1 表示未选中任何选项
  
  const updateChoice = val => {
    setChoice(val);
    console.log('当前选中的索引:', val);
  }

  // 监听choice变化,获取更新后的状态值
  useEffect(() => {
    console.log('更新后的choice状态:', choice);
  }, [choice])

  return (
    <MultipleChoice audioFiles={audioFiles} choice={choice} updateChoice={updateChoice} />
  )
};

MultipleChoice组件

const MultipleChoice = ({ audioFiles, choice, updateChoice }) => {
  const answerOption = audioFiles.map((item, key) =>
    // 修正file变量名,添加key属性
    <AudioButton file={item} index={key} choice={choice} updateChoice={updateChoice} key={key} />
  );
  // 用Fragment包裹返回的数组,符合JSX规范
  return <>{answerOption}</>;
}

AudioButton组件

const AudioButton = ({ file, index, choice, updateChoice }) => {
  const handleClick = (val) => {
    updateChoice(val);
  };

  const radioButton = (
    // 可根据需要补充样式,避免空div无法点击
    <div className={`${index === choice ? "selected" : ""}`} onClick={() => handleClick(index)}>
      {index === choice ? '●' : '○'}
    </div>
  );
  return (
    <>
      {radioButton}
      <Audio file={file} />
    </> 
  );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 02:24:02