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

React Native:导航返回按钮触发弹窗,自定义按钮返回不触发问题

React Native 解决自定义确认按钮返回触发未保存弹窗的问题

你遇到的问题主要有两个原因:

  1. React的setState是异步更新的,点击confirm按钮后立刻调用navigation.goBack()时,buttonClicked状态还没完成更新,导致拦截逻辑依然触发。
  2. 拦截逻辑的条件判断错误,使用了&&而非||,无法正确识别自定义按钮的点击操作。

修复步骤及代码

1. 纠正拦截逻辑的条件判断

在beforeRemove监听器中,只要满足「无未保存内容」或「点击了自定义确认按钮」任一条件,就直接放行返回操作,不需要弹窗:

if (!hasUnsavedChanges || buttonClicked) {
  return;
}

2. 解决setState异步问题

通过useEffect监听buttonClicked状态变化,确保状态更新完成后再执行返回操作,同时重置状态避免残留影响:

const EditTextScreen = ({ navigation }) => {
  const [text, setText] = React.useState('');
  const [buttonClicked, setButtonClicked] = React.useState(false);

  const hasUnsavedChanges = Boolean(text);

  // 监听buttonClicked状态,触发返回并重置状态
  React.useEffect(() => {
    if (buttonClicked) {
      navigation.goBack();
      setButtonClicked(false);
    }
  }, [buttonClicked, navigation]);

  React.useEffect(
    () =>
      navigation.addListener('beforeRemove', (e) => {
        const action = e.data.action;
        // 条件改为:无未保存内容 或 点击了确认按钮,直接放行
        if (!hasUnsavedChanges || buttonClicked) {
          return;
        }

        e.preventDefault();

        Alert.alert(
          'Discard changes?',
          'You have unsaved changes. Are you sure to discard them and leave the screen?',
          [
            { text: "Don't leave", style: 'cancel', onPress: () => {} },
            {
              text: 'Discard',
              style: 'destructive',
              onPress: () => navigation.dispatch(action),
            },
          ]
        );
      }),
    [hasUnsavedChanges, buttonClicked, navigation]
  );

  return (
    <View style={styles.content}>
      <TextInput
        autoFocus
        style={styles.input}
        value={text}
        placeholder="Type something…"
        onChangeText={setText}
      />
      {/* 点击按钮仅更新状态,返回操作由useEffect处理 */}
      <Button onPress={() => setButtonClicked(true)}>confirm</Button>
    </View>
  );
};

说明

  • 自定义确认按钮点击时仅更新buttonClicked状态,useEffect监听到状态变化后执行返回,此时buttonClicked已为true,拦截逻辑会直接放行。
  • 执行返回后重置buttonClicked为false,避免再次进入该页面时状态残留导致异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 13:28:26