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

React组件中单选按钮首次点击背景不更新问题排查

React单选按钮点击后样式延迟生效问题解决

问题描述

开发React表单时,期望选中单选按钮同步切换对应label的背景色,但首次点击仅更新组件状态,第二次点击才会显示背景色变化。使用onChange与checked属性管理单选按钮状态,相关组件及CSS代码如下:

Task组件代码

import React, { useState } from 'react';

export default function Task() {
  let [formData, setformData] = useState({
    uName: '', 
    uGender: '', 
    uMedals: 0, 
  });

  let handleForm = (e) => {
    let { name, value } = e.target;

    e.preventDefault();

    if (name === 'uMedals') {
      value = parseInt(value);

      if (value <= 0)
          value = 0;

      if (value > 20) 
          value = formData.uMedals;
    }

    setformData((formData) => ({
      ...formData,
      [name]: value,
    }));
  };

  return (
    <div className='parent-container'>
      <div className='content-wrapper'>
        <div className='left'>
          <form className='form-wrapper'>
            <div className='name-wrapper'>
              <label>Name</label>
              {/* Name input */}
            </div>
            <div className='toogle-wrapper'>
              <label className='lbl-gen'>Gender</label>
              <div className='wrapper'>
                <div className='custom-input'>
                  <input
                    type='radio'
                    id='female'
                    name='uGender'
                    value='female'
                    onChange={handleForm}
                    checked={formData.uGender === 'female'}
                  />
                  <label htmlFor='female'>Female</label>
                </div>
                <div className='custom-input'>
                  <input
                    type='radio'
                    id='male'
                    name='uGender'
                    value='male'
                    onChange={handleForm}
                    checked={formData.uGender === 'male'}
                  />
                  <label htmlFor='male'>Male</label>
                </div>
              </div>
            </div>
            <button style={{ width: '320px' }}>Add</button>
          </form>
        </div>
      </div>
    </div>
  );
}

CSS代码

.custom-input input[type=radio] {
    display: none;
}
.custom-input label {
    display: block;
    padding: 6px 8px;
    color: #fff;
    font-weight: bold;
    text-align: center;
    transition: all 0.4s ease;
    cursor: pointer;
    border-radius: 4px;
    background-color: #717762;
}
.custom-input input[type='radio']:checked + label {
    background-color: #f5f5f5; 
    color: #000;
}

问题原因

核心问题在于handleForm函数中调用了e.preventDefault(),而单选按钮的onChange事件不需要阻止默认行为。这一操作会干扰浏览器原生的单选按钮选中状态同步,导致CSS的:checked伪类在首次点击时无法正确触发——浏览器原生选中状态被阻止,而React状态更新是异步的,第二次点击时两者状态才对齐,样式才会生效。

解决方案

移除handleForm函数中的e.preventDefault(),因为单选按钮的onChange事件没有需要阻止的默认行为(表单提交的默认行为才需要在onSubmit中处理)。

修改后的handleForm函数代码:

let handleForm = (e) => {
  let { name, value } = e.target;

  // 移除阻止默认行为的代码
  // e.preventDefault();

  if (name === 'uMedals') {
    value = parseInt(value);

    if (value <= 0)
        value = 0;

    if (value > 20) 
        value = formData.uMedals;
  }

  setformData((formData) => ({
    ...formData,
    [name]: value,
  }));
};

效果验证

移除e.preventDefault()后,浏览器会正常更新单选按钮的原生选中状态,CSS的:checked伪类会即时触发,同时React状态也同步更新,首次点击单选按钮时就能看到对应label的背景色变化。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 17:20:14