javascript - 在导航之前反应回调没有得到更新
问题描述
我确定这是可以通过 修复的情况async/await
,但我看不出应该在哪里应用。
我有三个组件。一个组件是一个计时器,它接收来自父级的回调并返回计时器停止时剩余的剩余时间。父组件接收此数据并导航到结果页面。但是,导航发生在接收数据之前,因此不会传递。如果您向后导航并重复该过程,则会显示先前的数据,因此我知道它在理论上有效,但这只是等待数据到达的情况。
定时器组件
export const Timer = ({ seconds, timerRunning, checkForTimeLimit }) => {
const [timeLimit, settimeLimit] = React.useState(seconds);
const [timerActive, setTimerActive] = React.useState(timerRunning);
React.useEffect(() => {
setTimerActive(timerRunning);
settimeLimit(seconds);
return function cleanup() {
setTimerActive(false);
}
}, [timerRunning]);
React.useEffect(() => {
if (timeLimit > 0 && timerActive) {
setTimeout(() => {
settimeLimit(timeLimit - 1);
}, 1000);
}
if (timeLimit === 0 && timerRunning || !timerRunning) {
checkForTimeLimit(timeLimit); // When the timer is stopped, it passes back the remaining time
}
}, [timeLimit, timerActive]);
//...Other stuff
父组件
export const Test = ({ navigation, route }) => {
const [timerRunning, setTimerRunning] = React.useState(timerIsRunning);
const [secondsForTest, setSecondsForTest] = React.useState(minutes * 60);
const [remainingTime, setRemainingTime] = React.useState(0);
const handleCheckForTimeLimit = (timeLimit) => {
setRemainingTime(timeLimit); // Receives the remaining time from timer and sets to state
};
return (
<View style={{ flex: 1, margin: 10 }}>
{timed ? (
<Timer
seconds={secondsForTest}
timerRunning={timerRunning}
checkForTimeLimit={(
timeLimit // passes callback to timer
) => handleCheckForTimeLimit(timeLimit)}
/>
) : null}
<Button
onPress={() => {
setTimerRunning(false); // stops timer and triggers callback
setResponseDetails({ answered: false, index: null });
setActiveIndex(0);
setStoredResponses([]);
navigation.navigate('Results', {
// navigates to results page and passes in data
data: storedResponses,
category: category,
timed: timed,
minutes: minutes,
remainingTime: remainingTime,
});
}}
disabled={!responseDetails.answered}
style={styles.button}
>
<Text>Results</Text>
<Icon name="arrow-dropright" />
</Button>
</View>
);
};
结果页面
export const Results = ({ navigation, route }) => {
const { category, data: testData, timed, minutes, remainingTime } = route.params;
// remainingTime is not populated
}
我应该如何更新此代码以便remainingTime
填充并传递到结果页面?
解决方案
由于您的回调用于设置timeLimit
,因此导航应该是应用更改的效果timeLimit
(导航不应该在新闻处理程序中)。
因此,只需将您的导航包裹起来useCallback
,并将其作为依赖项传递给触发timeLimit
更改的效果。
更新
尝试使用附加状态以仅在按下按钮时允许导航。
export const Test = ({ navigation, route }) => {
const [timerRunning, setTimerRunning] = React.useState(timerIsRunning);
const [secondsForTest, setSecondsForTest] = React.useState(minutes * 60);
const [remainingTime, setRemainingTime] = React.useState(0);
// use additional state
const [isNavigationAllowed, setIsNavigationAllowed] = React.useState(false);
const handleCheckForTimeLimit = (timeLimit) => {
setRemainingTime(timeLimit); // Receives the remaining time from timer and sets to state
};
// move navigation into callback
const navigateToResult = useCallback(() => {
navigation.navigate("Results", {
data: storedResponses,
category: category,
timed: timed,
minutes: minutes,
remainingTime: remainingTime,
});
}, [storedResponses, category, timed, minutes, remainingTime]);
// navigate only when you allow it
useEffect(() => {
if (isNavigationAllowed) {
navigateToResult();
}
}, [navigateToResult, isNavigationAllowed]);
return (
<View style={{ flex: 1, margin: 10 }}>
{timed ? (
<Timer
seconds={secondsForTest}
timerRunning={timerRunning}
checkForTimeLimit={(
timeLimit // passes callback to timer
) => handleCheckForTimeLimit(timeLimit)}
/>
) : null}
<Button
onPress={() => {
setTimerRunning(false); // stops timer and triggers callback
setResponseDetails({ answered: false, index: null });
setActiveIndex(0);
setStoredResponses([]);
// allow navigation only after button is pressed
setIsNavigationAllowed(true);
}}
disabled={!responseDetails.answered}
style={styles.button}
>
<Text>Results</Text>
<Icon name="arrow-dropright" />
</Button>
</View>
);
};
推荐阅读
- sql - PSQL 更新一个 jsonb 属性,并连接到它的当前值
- angular - 从单个文档 Angular 和 Firestore 中检索值
- regex - grep 匹配整个证书?
- android - 仿真器:仿真器:错误:x86 仿真当前需要硬件加速
- javascript - 从 YouTube Player API 调用单个函数?
- unity3d - 相机显示远处的一条线
- ruby-on-rails - Trix 编辑器显示在 Localhost 但不显示在 Heroku (Rails 5.2)
- python - applescript 将文本传递给 python 脚本---stdout 的位被截断
- android - 为所有安卓手机设计
- numpy - 被 random.randn() 弄糊涂了