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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 06:27:04