如何将状态变量作为参数传入CommonActions.reset()指定的路由?
CommonActions.reset传递状态变量为空的问题解决
问题现象
定义状态变量quizID后,点击按钮单独打印该变量能输出正确值,但添加navigation.dispatch(CommonActions.reset())逻辑后,console.log(quizID)输出空字符串,导致无法将quizID作为参数传递给目标路由。
原因分析
核心原因是闭包捕获旧值或组件卸载触发状态重置:
- 若当前组件是被
CommonActions.reset从导航栈中移除的页面,调用reset时组件会被立即卸载,受React批量更新机制影响,状态可能提前被清空; - 事件回调的闭包可能捕获了旧的
quizID值,当quizID更新后,组件未生成新的回调函数,导致dispatch时使用的是初始空值。
解决方案
方案1:用useRef保存最新状态值
useRef的.current属性始终指向最新状态,不受闭包限制:
import { useRef, useState, useEffect } from 'react'; // 定义ref同步保存最新quizID const quizIDRef = useRef<string>(""); const [quizID, setQuizID] = useState<string>(""); // 状态更新时同步到ref useEffect(() => { quizIDRef.current = quizID; }, [quizID]); // 按钮回调中使用ref的值 <Button onPress={() => { console.log(quizIDRef.current); navigation.dispatch( CommonActions.reset({ index: 1, routes: [ { name: 'HomeScreenWithDrawer' }, { name: 'Quiz', params: {quizID: quizIDRef.current}, } ], }) ); }}/>
方案2:提前缓存状态到临时变量
在回调中先将当前quizID赋值给临时变量,确保传递的是最新值:
<Button onPress={() => { const currentQuizID = quizID; console.log(currentQuizID); navigation.dispatch( CommonActions.reset({ index: 1, routes: [ { name: 'HomeScreenWithDrawer' }, { name: 'Quiz', params: {quizID: currentQuizID}, } ], }) ); }}/>
方案3:提升状态到全局/父组件
如果当前组件会被reset操作卸载,建议将quizID状态迁移到不会被卸载的父组件,或使用React Context、Redux等全局状态容器,避免组件卸载导致状态丢失。
内容的提问来源于stack exchange,提问作者Buretto
相关产品推荐
相关产品推荐

