路由参数在重新渲染时仍然存在,这会导致无限的重新渲染循环,因为路由参数用于状态更改。
我有两个屏幕,主屏幕,
export default function Login({ route }: LoginProps) {
const loginfn = (data) => {
setInProgressState(true)
// do login }
}
const scannedData = route.params.data
if(scannedData) { // problematic part
loginfn(scannedData)
}
return {
{InProgressState && (
<InProgressAlert/>
)}
<QRCodeScanner/>
<TextInputLogin/>
}
}
二维码屏幕,
export default function QRCodeScanner() {
return {
<Scanner
onScan={() => { navigation.navigate(ROUTE.LOGIN, {data: barcode.data}) }}
/>
}
}
现在的问题是因为
loginfn
改变状态并触发重新渲染,它再次检查 if 条件并再次调用 loginfn
,这会导致“太多重新渲染”错误。我预计第一次渲染后每次重新渲染时路由参数都为空,但事实并非如此,这导致了此问题。
我能得到的最接近的是
const scannedData = route.params.data
useEffect(() => {
if(scannedData) { // problematic part
loginfn(scannedData)
}
}, [route.params.data])
但是这只有效一次。如果再次扫描相同的二维码,路线参数不会更改,因此不会触发
useEffect
。
我不太了解 React,但我可以理解某些地方潜伏着一些反模式,但我无法理解它是什么。有没有更好的方法将数据从一个屏幕发送到另一个屏幕而不持续重新渲染?
我发现一个可行的解决方案仍然可能不是最好的。
useEffect
在路由参数中传递相同数据时会出现无法工作的问题,useFocusEffect
每次导航页面时都会工作,即使使用相同的路由参数也是如此。
scannedData = route?.params.data
useFocusEffect(
React.useCallback(() => {
if(scannedData) {
loginfn(scannedData)
}
}, [route?.params.data, loginfn]),
)
因为
useFocusEffect
每次导航到时都会触发回调,并且 useCallback
负责避免无限重新渲染循环,因为它的依赖项没有改变。