单击开关不会在第一次更改状态,前提是它已经选中



我是React的新手,刚刚开始在本地开发一个管理面板来实践我所学到的东西,我遇到了这个问题,在搜索了很长一段时间后,我无法解决它,我几乎要踩到小猫和无辜的孩子了。。。

情况是这样的:

我有一个用于注册一些产品的面板,比如说,鞋子,在我的管理面板的仪表板页面上,我列出了我的产品,我可以点击其中任何一个上的编辑来重定向到编辑页面,并更改信息,如名称、价格、图像等。

到目前为止,一切都按预期进行,问题是我有一个Switch Input,它可以指示它是否是特色产品,当我登录编辑页面时,它会正确显示它是打开还是关闭,现在当我点击它以更改其状态时,我第一次点击时什么都没有发生,它在第二次点击后开始工作。

我已经做了研究,知道这与使用useEffect((等有关,我也相应地更改了代码,现在真正的问题是,当我登录编辑页面时,开关关闭时,第一次点击时,它工作得很好,它变为on,我可以保存它,它会按预期进行,但如果我登录编辑页时默认为on,第一次点击不起作用,需要2次或更多的点击才能改变状态,我无法理解它在关闭时是如何工作的,而不是双向的。

这是我第一次在这里提问,所以我可能没有足够清楚或恰当地表达我的问题,所以我提前道歉。

这是代码:

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 [switchVal, setSwitchVal] = useState(); // this is the state I use for the switch but would rather have it in the 'product' state above so they are all together
const switchHandler = (e) => { // the onChange function for the switch
const curVal = e.target.checked
setSwitchVal(curVal)
}
useEffect(() => { // the useEffect to reflect switch changes
setProduct({
...product,
feat: switchVal
})
console.log(switchVal)
}, [switchVal, setSwitchVal]);
const changeHandler = (e) => { // the input handler for all other inputs
setProduct({
...product,
[e.target.name]: e.target.value,
})
}
const editProductSubmit = (e) => { // form onSubmit
e.preventDefault()
dispatch({
type: 'EDIT_PRODUCT',
payload: {
productId,
product
}
})
redirect("/admin/dashboard")
}
const fetchedId = useParams()
const productId = fetchedId.id
useEffect(() => {
const fetchedProduct = async () => {
try {
const {data} = await getOneProduct(productId) // axios.get()
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
defaultValue={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
defaultValue={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
defaultValue={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
defaultValue={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
defaultValue={product.image}
onChange={changeHandler}
type="text"
className="form-control"
id="productImage"
name="image"
placeholder="لینک تصویر محصول"
/>
<label className="form-label" htmlFor="productImage">لینک تصویر محصول</label>
</div>
<div className="form-check form-switch form-check-reverse mb-3">
<input
onChange={switchHandler}
defaultChecked={product.feat}
value={switchVal}
type="checkbox"
className="form-check-input"
id="productFeat"
role="switch"
/> {/* This is the switch in question */}
<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;

如果将const [switchVal, setSwitchVal] = useState();设置为const [switchVal, setSwitchVal] = useState(false);,则其起始值将为false,而不是undefined。假设在渲染时必须取消选中该框。如果需要在渲染时为true,只需将其更改为true即可。

最新更新