Redux存储正在更新,但由setInterval调用的连接函数仍然会看到旧状态

时间:2017-02-12 18:20:07

标签: javascript reactjs redux setinterval react-redux

我正在尝试让我的应用具有以下行为:   - 当用户单击“开始计时器”时,计时器运行   - 计时器结束时,将向控制台输出一条消息   - 显示自计时器启动以来经过的秒数

我的项目位于: 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,因此永远不会打印定时器已完成。

我尝试过的事情没有成功:

  • 我尝试过包括或不包括handleTick 组件的mapDispatchToProps。
  • 当我把它传递给函数时,我尝试在函数中包装handleTick 的setInterval。
  • 我已经尝试将道具传递给handleTick而不是传递它们 为了使用封闭范围。
  • 我试过绑定handleTick的“this”;但是,我得到了“这个” 未定义。
  • 我尝试将handleTick定义为startTimers的嵌套函数 看看这是否会以某种方式让它具有正确的范围。
  • 我尝试了以前方法的各种组合。

我猜测我处理范围错误或者Redux如何将状态传递给组件或重新呈现我不理解的一些方面。我做错了什么?

2 个答案:

答案 0 :(得分:0)

我将状态传递给子节点时遇到了麻烦,除非它们是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>
);
&#13;
&#13;
&#13;

答案 1 :(得分:0)

对,

单击startTimers时,在控制器中

,tickCounter为0.在您的间隔范围内,它永远不会更新。因此handleTick将始终读取值0。

是的,incrementAction执行工作并且商店中的tickCounter得到更新,但你的actionCreator函数(handleStartTimers)中没有状态对象,这就是下面的表达式始终为false的原因:

if (tickCount === duration * 60){

一种简单的修复方法,就是在区间内执行增量,而不是动作,它也有意义,因为你处理时间,所以你不能依赖setInterval函数,因为它永远不会是100%1000毫秒,但总是在1000毫秒后。所以你可以设置如下:

var startTime = new Date().getTime();
var intervalId = window.setInterval(() => {
  var seconds = Math.round((new Date().getTime() - startTime) / 1000);
  setPassedSeconds(seconds, intervalId);
}, 1000);

这样您也可以更改间隔时间,而无需更改操作/缩减器中的代码..