React Ionic中如何阻止ion-toggle的onIonChange在页面加载时触发
问题解决方法
根本原因
Ionic的IonToggle组件的onIonChange事件,不只会在用户手动点击切换开关时触发,只要checked属性值发生变化(包括代码主动修改状态赋值)就会触发。你场景中触发的逻辑是:
- 页面初始化时
covidDetails的两个字段默认值为false,开关默认关闭 - 接口请求返回后端真实状态后,你更新了
covidDetails字段值,开关的checked属性被代码修改,就触发了绑定的提交接口逻辑
修改方案
新增一个初始化状态标记位,在接口数据未加载完成前,拦截onIonChange的提交逻辑即可,完整修改后的代码如下:
import { IonToggle, IonItem, IonLabel } from '@ionic/react'; import { useEffect, useState } from 'react'; import axios from 'axios'; import { apiUrl } from '../../utils/apiUrl'; import Cookies from 'universal-cookie'; const cookies = new Cookies(); // 补充你漏写的cookies实例化 const Sample: React.FC = () => { // 新增初始化标记位,默认是正在初始化 const [isInitialLoad, setIsInitialLoad] = useState(true); const [covidDetails, setCovidDetails] = useState<{ firstDose?: boolean, secondDose?: boolean }>({ firstDose: false, secondDose: false }); const getCovidVaccine = async () => { try { const response = (await axios.get(`${apiUrl()}/user/getCovidVaccineDetails/{userIdfromcookie}`, { headers: { Authorization: `Bearer ${cookies.get('token')}` } })).data; if (response.covidVaccine !== null) { setCovidDetails({ firstDose: response.covidVaccine.firstDose, secondDose: response.covidVaccine.secondDose }) } // 数据更新完成后,标记初始化结束 setIsInitialLoad(false); } catch (error) { console.log(error); // 接口报错也需要标记初始化结束,避免用户后续操作无法触发逻辑 setIsInitialLoad(false); } } const setCovidVaccine = async (e) => { // 初始化阶段直接拦截,不执行提交逻辑 if (isInitialLoad) return; try { console.log("first", covidDetails); var details = { firstDose: covidDetails.firstDose, secondDose: covidDetails.secondDose }; if (e.detail.value === "firstDose") { details.firstDose = e.detail.checked; } if (e.detail.value === "secondDose") { details.secondDose = e.detail.checked; } const response = (await axios.post(`${apiUrl()}/user/setCovidVaccineDetails/{userIdfromcookie}`, details, { headers: { Authorization: `Bearer ${cookies.get('token')}` } })).data; if (response.covidVaccine !== null) { setCovidDetails({ firstDose: response.covidVaccine.firstDose, secondDose: response.covidVaccine.secondDose }) } } catch (error) { console.log(error); } } useEffect(() => { getCovidVaccine(); }, []); return ( <div> <IonItem> <IonLabel className={styles.vaccineLabel}> <p>1st Dose Vaccine</p> </IonLabel> <IonToggle color="primary" checked={covidDetails.firstDose} value="firstDose" onIonChange={e => setCovidVaccine(e)} /> </IonItem> <IonItem> <IonLabel className={styles.vaccineLabel}> <p>2nd Dose Vaccine</p> </IonLabel> <IonToggle color="primary" checked={covidDetails.secondDose} value="secondDose" onIonChange={e => setCovidVaccine(e)} /> </IonItem> </div> ); }
核心修改点
- 新增
isInitialLoad状态标记初始化阶段 - 在
setCovidVaccine逻辑最开头加判断,初始化阶段直接返回不执行提交 - 接口请求无论成功失败,都要把
isInitialLoad设为false,保证后续用户操作能正常触发提交
内容的提问来源于stack exchange,提问作者Sriharsha K
相关产品推荐
相关产品推荐

