Redux 存储正在更新,但 setInterval 调用的连接函数仍然看到旧状态
Redux store is updating but connected function that is called by setInterval still sees the old state
我试图让我的应用程序具有以下行为:
- 当用户单击 "Start Timers" 时,计时器运行
- 计时器结束时,控制台会打印一条消息
- 显示计时器启动后经过的秒数
我的项目在:
https://github.com/harimau777/reduxTimerExample
我的实施策略是:
当用户单击 "Start Timers" 时,将调用 handleStartTimers。 handleStartTimers 开始一个持续时间为一秒的间隔,它在到期时调用 handleTick。然后它会调度一个 startTimers 动作。
handleTick的大体逻辑是:
if this is the last tick in the timer:
Print that the timer has finished
Reset the timer
else:
Dispatch an incrementTickCount action
我遇到的问题是:
- 当我点击 startTimers 时,从开始的秒数
页面上显示的计时器每秒递增一次。这表明
商店正在正确更新并且 handleTick 是
成功调度 incrementTickCount 操作。
- 但是,handleTick 永远不会获得更新状态,所以它总是看到
tickCount 为 0,因此永远不会打印计时器已完成。
我尝试过但没有成功的事情:
- 我试过在
组件的 mapDispatchToProps.
- 当我将 handleTick 传递给
设置间隔。
- 我试过将道具传递给 handleTick 而不是传递它们
为了使用闭包范围。
- 我试过绑定 handleTick 的 "this";但是,我明白了 "this"
未定义。
- 我试过将 handleTick 定义为 startTimers 的嵌套函数
看看这是否会以某种方式允许它具有正确的范围。
- 我尝试了以前方法的各种组合。
我猜测要么我处理范围错误,要么我不理解 Redux 如何将状态传递给组件或重新呈现的某些方面。我做错了什么?
我无法将状态传递给子级,除非它们是 mapStateToProps 中的一阶值。试试这个;
const TimerList = ({timers, increment, decrement, addTimer, removeTimer}) => (
<div className="timerList">
{console.log('Timers are:', timers)}
{
timers.map((timer, index) => (
<div key={index}>
<div className="timer">
<h1>Timer {index}</h1>
<span>Duration: {timer} minutes</span>
<span className='button' onClick={() => increment(index)}>Increment</span>
<span className='button' onClick={() => decrement(index)}>Decrement</span>
</div>
<span className="button" onClick={() => removeTimer(index)}>Remove Timer</span>
</div>
))
}
<span className="button" onClick={addTimer}>Add Timer</span>
</div>
);
对,
在您的控制器中,当您单击 startTimers 时,tickCounter 为 0。在您的间隔范围内,它永远不会更新。所以 handleTick
将始终读取值 0。
是的,incrementAction 执行工作并且您商店中的 tickCounter 得到更新,但是您的 actionCreator 函数 (handleStartTimers) 中没有状态对象,这就是以下表达式始终为 false 的原因:
if (tickCount === duration * 60){
修复它的一个简单方法是在间隔内执行递增,而不是操作,这也很有意义,因为您正在处理时间,所以您不能依赖 setInterval 函数,因为它永远不会是 100% 1000ms,但总是在 1000ms 之后。所以你可以这样设置:
var startTime = new Date().getTime();
var intervalId = window.setInterval(() => {
var seconds = Math.round((new Date().getTime() - startTime) / 1000);
setPassedSeconds(seconds, intervalId);
}, 1000);
通过这种方式,您还可以更改间隔时间,而无需更改操作/reducer 中的代码。
我试图让我的应用程序具有以下行为: - 当用户单击 "Start Timers" 时,计时器运行 - 计时器结束时,控制台会打印一条消息 - 显示计时器启动后经过的秒数
我的项目在: https://github.com/harimau777/reduxTimerExample
我的实施策略是: 当用户单击 "Start Timers" 时,将调用 handleStartTimers。 handleStartTimers 开始一个持续时间为一秒的间隔,它在到期时调用 handleTick。然后它会调度一个 startTimers 动作。
handleTick的大体逻辑是:
if this is the last tick in the timer:
Print that the timer has finished
Reset the timer
else:
Dispatch an incrementTickCount action
我遇到的问题是:
- 当我点击 startTimers 时,从开始的秒数 页面上显示的计时器每秒递增一次。这表明 商店正在正确更新并且 handleTick 是 成功调度 incrementTickCount 操作。
- 但是,handleTick 永远不会获得更新状态,所以它总是看到 tickCount 为 0,因此永远不会打印计时器已完成。
我尝试过但没有成功的事情:
- 我试过在 组件的 mapDispatchToProps.
- 当我将 handleTick 传递给 设置间隔。
- 我试过将道具传递给 handleTick 而不是传递它们 为了使用闭包范围。
- 我试过绑定 handleTick 的 "this";但是,我明白了 "this" 未定义。
- 我试过将 handleTick 定义为 startTimers 的嵌套函数 看看这是否会以某种方式允许它具有正确的范围。
- 我尝试了以前方法的各种组合。
我猜测要么我处理范围错误,要么我不理解 Redux 如何将状态传递给组件或重新呈现的某些方面。我做错了什么?
我无法将状态传递给子级,除非它们是 mapStateToProps 中的一阶值。试试这个;
const TimerList = ({timers, increment, decrement, addTimer, removeTimer}) => (
<div className="timerList">
{console.log('Timers are:', timers)}
{
timers.map((timer, index) => (
<div key={index}>
<div className="timer">
<h1>Timer {index}</h1>
<span>Duration: {timer} minutes</span>
<span className='button' onClick={() => increment(index)}>Increment</span>
<span className='button' onClick={() => decrement(index)}>Decrement</span>
</div>
<span className="button" onClick={() => removeTimer(index)}>Remove Timer</span>
</div>
))
}
<span className="button" onClick={addTimer}>Add Timer</span>
</div>
);
对,
在您的控制器中,当您单击 startTimers 时,tickCounter 为 0。在您的间隔范围内,它永远不会更新。所以 handleTick
将始终读取值 0。
是的,incrementAction 执行工作并且您商店中的 tickCounter 得到更新,但是您的 actionCreator 函数 (handleStartTimers) 中没有状态对象,这就是以下表达式始终为 false 的原因:
if (tickCount === duration * 60){
修复它的一个简单方法是在间隔内执行递增,而不是操作,这也很有意义,因为您正在处理时间,所以您不能依赖 setInterval 函数,因为它永远不会是 100% 1000ms,但总是在 1000ms 之后。所以你可以这样设置:
var startTime = new Date().getTime();
var intervalId = window.setInterval(() => {
var seconds = Math.round((new Date().getTime() - startTime) / 1000);
setPassedSeconds(seconds, intervalId);
}, 1000);
通过这种方式,您还可以更改间隔时间,而无需更改操作/reducer 中的代码。