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
相关产品推荐
相关产品推荐

