React.js中onChange触发axios Post传单选框值为空问题
React单选框onChange后axios POST传值为空的问题修复
问题根源分析
- 状态更新异步特性导致旧值问题:React的useState更新是异步的,调用
setTemperatureMode2后,temp_mode_val不会立刻更新,此时调用SetTemperatureMode会拿到更新前的旧值。 - 单选框onChange传参错误:除Heat选项外,其余Cool/Auto/Off的onChange直接传递字符串(如
HeatHandleChange('cool')),但HeatHandleChange期望接收事件对象e,这会导致e.target.value报错,无法正确设置状态。 - 冗余依赖状态值:
SetTemperatureMode已接收data参数,却仍依赖temp_mode_val,放大了异步更新的影响。 - 未定义变量报错:原代码
then回调中的val和setVal未定义,属于笔误。
修复后的完整代码
const DiscoverOffice = () => { const { entity_id } = useParams(); const [temp_mode_val, setTemperatureMode2] = useState('off'); const SetTemperatureMode = async(mode) => { console.log("Body sent to server", { entity_id: entity_id, operation_mode: mode }); try { const result = await axios.post('xxx.com', { entity_id: entity_id, operation_mode: mode }, { headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${cookies.get('accesstoken')}` }, }); console.log(result.data); console.log(entity_id); console.log('Set Mode!'); // 若需同步本地状态,可在此调用setTemperatureMode2(mode) // getDevices(); } catch (err) { console.log(err); console.log(entity_id); console.log('Missed set Mode!'); } }; const HeatHandleChange = (e) => { const mode = e.target.value; setTemperatureMode2(mode); SetTemperatureMode(mode); }; const handleModeChange = (mode) => { setTemperatureMode2(mode); SetTemperatureMode(mode); }; return ( <> <div className="ic_schedule_label flex"> <input className="heat_mode_radio" type="radio" value="heat" onChange={HeatHandleChange} checked={temp_mode_val === 'heat'} /> <p className="radio_text">Heat</p> </div> <div className="ic_schedule_label flex"> <input className="heat_mode_radio" type="radio" value="cool" onChange={() => handleModeChange('cool')} checked={temp_mode_val === 'cool'} /> <p className="radio_text">Cool</p> </div> <div className="ic_schedule_label flex"> <input className="heat_mode_radio" type="radio" value="auto" onChange={() => handleModeChange('auto')} checked={temp_mode_val === 'auto'} /> <p className="radio_text">Auto</p> </div> <div className="ic_schedule_label flex"> <input className="heat_mode_radio" type="radio" value="off" onChange={() => handleModeChange('off')} checked={temp_mode_val === 'off'} /> <p className="radio_text">Off</p> </div> </> ); }; export default DiscoverOffice;
关键修改说明
- 移除异步状态依赖:
SetTemperatureMode直接使用传入的mode参数,彻底避免异步更新导致的旧值问题。 - 统一事件处理逻辑:新增
handleModeChange函数处理直接传模式字符串的场景,解决事件对象报错问题;Heat选项的处理也提取出mode变量,逻辑更一致。 - 优化异步代码结构:将
.then/.catch改为try/catch,契合async/await的写法规范,代码可读性更强。 - 清理无效代码:删除未定义的
val和setVal相关代码,消除潜在报错。
内容的提问来源于stack exchange,提问作者user20271619
相关产品推荐
相关产品推荐

