React Native:清除重渲染路由参数,解决无限重渲染问题
解决方案
问题根源
- 直接在组件渲染逻辑中调用
loginfn(修改状态的函数)属于React反模式,每次渲染都会执行,状态更新又触发重渲染,形成无限循环。 - 使用
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
相关产品推荐
相关产品推荐

