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

React Native:清除重渲染路由参数,解决无限重渲染问题

解决方案

问题根源

  1. 直接在组件渲染逻辑中调用loginfn(修改状态的函数)属于React反模式,每次渲染都会执行,状态更新又触发重渲染,形成无限循环。
  2. 使用useEffect监听路由参数时,若扫描相同二维码,路由参数未变化,useEffect的依赖项不变,不会重新执行,导致无法触发登录逻辑。

可行方案

方案1:处理完参数后清除路由参数

核心思路是在useEffect中处理完登录逻辑后,立即清除路由的data参数,这样即使扫描相同二维码,路由参数会从undefined变为目标值,useEffect会再次触发。

修改Login组件:

import { useNavigation } from '@react-navigation/native';
import { useState, useEffect } from 'react';

export default function Login({ route }: LoginProps) {
  const navigation = useNavigation();
  const [inProgressState, setInProgressState] = useState(false);

  const loginfn = async (data) => { 
    setInProgressState(true);
    try {
      // 执行登录逻辑
      // await loginApi(data);
    } finally {
      setInProgressState(false);
    }
  };

  useEffect(() => {
    const scannedData = route.params?.data;
    if (scannedData) {
      loginfn(scannedData);
      // 清除路由参数,避免重渲染时重复触发
      navigation.setParams({ data: undefined });
    }
  }, [route.params?.data, navigation]);

  return (
    <>
      {inProgressState && <InProgressAlert/>}
      <QRCodeScanner/>
      <TextInputLogin/>
    </>
  );
}

修改QRCodeScanner组件(补充navigation传递):

export default function QRCodeScanner({ navigation }) {
  return (
    <Scanner
      onScan={(barcode) => { 
        // 先清除可能残留的参数,再传递新参数
        navigation.setParams({ data: undefined });
        navigation.navigate(ROUTE.LOGIN, { data: barcode.data });
      }}
    />
  );
}

方案2:组件回调直接传参(更简洁)

放弃路由参数传参,直接通过组件回调的方式让QRCodeScanner把扫描结果传给Login组件,完全避免路由参数残留的问题。

修改Login组件:

import { useState } from 'react';

export default function Login() {
  const [inProgressState, setInProgressState] = useState(false);

  const loginfn = async (data) => { 
    setInProgressState(true);
    try {
      // 执行登录逻辑
      // await loginApi(data);
    } finally {
      setInProgressState(false);
    }
  };

  // 接收扫描结果的回调函数
  const handleScan = (scannedData) => {
    loginfn(scannedData);
  };

  return (
    <>
      {inProgressState && <InProgressAlert/>}
      <QRCodeScanner onScan={handleScan}/>
      <TextInputLogin/>
    </>
  );
}

修改QRCodeScanner组件:

export default function QRCodeScanner({ onScan }) {
  return (
    <Scanner
      onScan={(barcode) => { 
        onScan(barcode.data);
      }}
    />
  );
}

关键要点

  • 永远不要在组件的渲染阶段(函数体直接执行)调用修改状态的函数,这必然会导致无限重渲染。
  • 跨组件传参时,父子组件直接用回调比路由参数更可控,尤其适合需要重复触发相同逻辑的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 05:51:23