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

仅当Switch初始为选中状态时,首次点击无法切换状态

React Switch组件初始选中时首次点击无响应问题修复

问题根源

你的问题核心在于状态拆分维护+非受控组件混合写法导致的状态不同步:

  1. 单独维护switchVal和product两个状态,初始switchVal为undefined,当产品feat初始为true时,两者未同步初始化,第一次点击时状态更新逻辑冲突。
  2. Switch组件使用defaultChecked(非受控写法),同时又试图用switchVal控制状态,这种混合写法让React无法正确追踪组件状态。
  3. 用useEffect同步switchVal到product属于冗余操作,还会因闭包问题导致状态更新不及时。

修复步骤 & 完整代码

核心修改点

  1. 删除单独的switchVal状态,直接复用product.feat统一管理Switch状态
  2. 将Switch改为受控组件,用checked={product.feat}替代defaultChecked
  3. 修改输入处理逻辑,让Switch复用统一的changeHandler,去掉冗余的同步useEffect
  4. 所有输入组件从defaultValue改为value,统一使用受控组件写法
import { useEffect, useState } from "react";
import { useNavigate, useParams } from "react-router-dom";
import getOneProduct from "../../../Services/getOneProduct";
import { useProductsDispatch } from "../../../Context/productsContext";
import { toast } from "react-toastify";

function EditProductForm() {
    const dispatch = useProductsDispatch();
    const redirect = useNavigate();
    const [product, setProduct] = useState({
        name: '',
        desc: '',
        price: '',
        offPrice: '',
        image: '',
        feat: null,
        uid: '',
        date: '',
    });

    // 统一处理所有输入,自动适配复选框和普通输入
    const changeHandler = (e) => {
        const value = e.target.type === 'checkbox' ? e.target.checked : e.target.value;
        setProduct(prev => ({
            ...prev,
            [e.target.name]: value,
        }));
    };

    const editProductSubmit = (e) => {
        e.preventDefault();
        dispatch({
            type: 'EDIT_PRODUCT',
            payload: {
                productId,
                product
            }
        });
        redirect("/admin/dashboard");
    };

    const { id: productId } = useParams();
    useEffect(() => {
        const fetchedProduct = async () => {
            try {
                const { data } = await getOneProduct(productId);
                setProduct({
                    name: data.name,
                    desc: data.desc,
                    price: data.price,
                    offPrice: data.offPrice,
                    image: data.image,
                    feat: data.feat,
                    uid: data.uid,
                    date: data.date,
                });
            } catch (error) {
                console.log(error);
            }
        };
        fetchedProduct();
    }, [productId]);

    return (
        <div>
            <form className="add-product-form" onSubmit={editProductSubmit}>
                <div className="form-floating mb-3">
                    <input
                        value={product.name}
                        onChange={changeHandler}
                        type="text"
                        className="form-control"
                        id="productName"
                        name="name"
                        placeholder="نام محصول"
                    />
                    <label className="form-label" htmlFor="productName">نام محصول</label>
                </div>
                <div className="form-floating mb-3">
                    <textarea
                        value={product.desc}
                        onChange={changeHandler}
                        className="form-control"
                        id="productDesc"
                        name="desc"
                        placeholder="Leave a comment here"
                        style={{ height: 200 }}
                    />
                    <label htmlFor="productDesc">توضیحات محصول</label>
                </div>
                <div className="form-floating mb-3">
                    <input
                        value={product.price}
                        onChange={changeHandler}
                        type="number"
                        className="form-control"
                        id="productPrice"
                        name="price"
                        placeholder="قیمت اصلی محصول"
                    />
                    <label className="form-label" htmlFor="productPrice">قیمت اصلی محصول</label>
                </div>
                <div className="form-floating mb-3">
                    <input
                        value={product.offPrice}
                        onChange={changeHandler}
                        type="number"
                        className="form-control"
                        id="productOffPrice"
                        name="offPrice"
                        placeholder="قیمت با تخفیف محصول"
                    />
                    <label className="form-label" htmlFor="productOffPrice">قیمت با تخفیف محصول</label>
                </div>
                <div className="form-floating mb-3">
                    <input
                        value={product.image}
                        onChange={changeHandler}
                        type="text"
                        className="form-control"
                        id="productImage"
                        name="image"
                        placeholder="لینک تصویر محصول"
                    />
                    <label className="form-label" htmlFor="productImage">لینک تصویر محصول</label>
                </div>
                {/* 修复后的Switch组件 */}
                <div className="form-check form-switch form-check-reverse mb-3">
                    <input
                        onChange={changeHandler}
                        checked={product.feat}
                        type="checkbox"
                        className="form-check-input"
                        id="productFeat"
                        name="feat"
                        role="switch"
                    />
                    <label className="form-check-label" htmlFor="productFeat">محصول ویژه است</label>
                </div>
                <div className="mb-3">
                    <button type="submit" className="btn btn-success">ویرایش محصول</button>
                </div>
            </form>
        </div>
    );
}

export default EditProductForm;

额外说明

统一使用受控组件写法后,所有表单状态都集中在product对象中,避免了多状态同步的问题;同时复用changeHandler减少了代码冗余,让逻辑更清晰。

内容的提问来源于stack exchange,提问作者Mansour Sarhani

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 13:40:26