React Native按钮点击重复跳转:useState更新不及时无法禁用按钮
解决登录按钮重复点击导致首页多次入栈的问题
问题原因
- useState异步更新延迟:你用
useState维护的isPending状态更新是异步的,第一次点击调用setIsPending(true)后,isPending不会立刻变为true。此时快速重复点击,if(isPending) return的判断会失效,因为isPending还是初始的false。 - 状态重置时机错误:如果业务逻辑和接口请求是异步操作,但代码里没通过
await等待完成就直接调用setIsPending(false),会导致按钮很快恢复可点击状态,用户仍能多次触发点击。
解决方案
方案1:用useRef同步跟踪点击状态
useRef的current属性是同步更新的,能立刻拦截后续点击,配合useState控制按钮禁用状态:
import { useState, useRef } from 'react'; // 用ref同步跟踪pending状态,用useState控制UI禁用状态 const isPendingRef = useRef(false); const [isPending, setIsPending] = useState(false); const onSignInPressed = async (e) => { // 用ref判断,避免异步延迟导致的重复点击 if (isPendingRef.current) return; // 同步更新ref,立刻拦截后续点击 isPendingRef.current = true; // 更新useState,让按钮变为禁用状态 setIsPending(true); try { // 等待所有异步业务逻辑和接口请求完成 await yourLoginApi(); // 替换成你实际的接口请求函数 // 跳转到首页 navigation.navigate('homeScreen'); } catch (err) { // 可添加错误提示,比如Toast console.log('登录失败:', err); } finally { // 不管成功失败,都重置状态 isPendingRef.current = false; setIsPending(false); } };
按钮代码保持不变:
<Button containerStyle={styles.loginContainer} style={styles.loginText} disabled={isPending} onPress={onSignInPressed}> Se connecter(登录) </Button>
方案2:跳转前检查当前路由,避免重复入栈
在跳转到首页前,先判断当前页面是否已经是首页,就算按钮被多次点击,也不会重复推入页面:
// 在跳转逻辑中添加判断 const currentRoute = navigation.getCurrentRoute(); if (currentRoute?.name !== 'homeScreen') { navigation.navigate('homeScreen'); }
建议将两个方案结合使用,实现双重保险。
内容的提问来源于stack exchange,提问作者Akrem Gomri
相关产品推荐
相关产品推荐

