当前位置: 首页 > 面试题库 >

使用Redux创建秒表

柳飞鸾
2023-03-14
问题内容

我一直在尝试使React和Redux成为秒表。我一直在寻找如何在Redux中设计这样的东西的麻烦。

我想到的第一件事是要执行一个START_TIMER设置初始offset值的操作。在那之后,我使用一遍又一遍地setInterval触发一个TICK操作,该操作使用偏移量来计算经过了多少时间,将其添加到当前时间,然后更新offset

这种方法似乎有效,但是我不确定如何清除间隔来停止它。另外,似乎这种设计很差,并且可能有更好的方法来做。

这是一个完整的JSFiddle,具有START_TIMER正常工作的功能。如果您只是想看看我的减速器现在是什么样子,请看这里:

const initialState = {
  isOn: false,
  time: 0
};

const timer = (state = initialState, action) => {
  switch (action.type) {
    case 'START_TIMER':
      return {
        ...state,
        isOn: true,
        offset: action.offset
      };

    case 'STOP_TIMER':
      return {
        ...state,
        isOn: false
      };

    case 'TICK':
      return {
        ...state,
        time: state.time + (action.time - state.offset),
        offset: action.time
      };

    default: 
      return state;
  }
}

我真的很感谢您的帮助。


问题答案:

我可能会建议采取不同的处理方式:仅将计算经过时间所需的状态存储在存储中,让组件设置其 自己的 间隔,以便他们经常希望更新显示。

这样可以将动作调度减至最少-仅调度启动和停止(和重置)计时器的动作。请记住,您 每次 分派操作
都会返回一个新的状态对象,然后每个connected组件都会重新渲染(即使它们使用优化来避免在封装的组件内部进行过多的重新渲染)。此外,由于您必须与所有TICK其他动作一起处理所有操作,因此许多动作分派可能使调试应用程序状态更改变得困难。

这是一个例子:

// Action Creators

function startTimer(baseTime = 0) {
  return {
    type: "START_TIMER",
    baseTime: baseTime,
    now: new Date().getTime()
  };
}

function stopTimer() {
  return {
    type: "STOP_TIMER",
    now: new Date().getTime()
  };
}

function resetTimer() {
  return {
    type: "RESET_TIMER",
    now: new Date().getTime()
  }
}


// Reducer / Store

const initialState = {
  startedAt: undefined,
  stoppedAt: undefined,
  baseTime: undefined
};

function reducer(state = initialState, action) {
  switch (action.type) {
    case "RESET_TIMER":
      return {
        ...state,
        baseTime: 0,
        startedAt: state.startedAt ? action.now : undefined,
        stoppedAt: state.stoppedAt ? action.now : undefined
      };
    case "START_TIMER":
      return {
        ...state,
        baseTime: action.baseTime,
        startedAt: action.now,
        stoppedAt: undefined
      };
    case "STOP_TIMER":
      return {
        ...state,
        stoppedAt: action.now
      }
    default:
      return state;
  }
}

const store = createStore(reducer);

请注意,动作创建者和缩减者仅处理原始值,并且不使用任何类型的间隔或TICK动作类型。现在,组件可以轻松地订阅此数据并根据需要进行更新:

// Helper function that takes store state
// and returns the current elapsed time
function getElapsedTime(baseTime, startedAt, stoppedAt = new Date().getTime()) {
  if (!startedAt) {
    return 0;
  } else {
    return stoppedAt - startedAt + baseTime;
  }
}

class Timer extends React.Component {
  componentDidMount() {
    this.interval = setInterval(this.forceUpdate.bind(this), this.props.updateInterval || 33);
  }

  componentWillUnmount() {
    clearInterval(this.interval);
  }

  render() {
    const { baseTime, startedAt, stoppedAt } = this.props;
    const elapsed = getElapsedTime(baseTime, startedAt, stoppedAt);

    return (
      <div>
        <div>Time: {elapsed}</div>
        <div>
          <button onClick={() => this.props.startTimer(elapsed)}>Start</button>
          <button onClick={() => this.props.stopTimer()}>Stop</button>
          <button onClick={() => this.props.resetTimer()}>Reset</button>
        </div>
      </div>
    );
  }
}

function mapStateToProps(state) {
  const { baseTime, startedAt, stoppedAt } = state;
  return { baseTime, startedAt, stoppedAt };
}

Timer = ReactRedux.connect(mapStateToProps, { startTimer, stopTimer, resetTimer })(Timer);

您甚至可以在同一数据上以不同的更新频率显示多个计时器:

class Application extends React.Component {
  render() {
    return (
      <div>
        <Timer updateInterval={33} />
        <Timer updateInterval={1000} />
      </div>
    );
  }
}
您可以在此处查看具有此实现的 有效JSBin: https
//jsbin.com/dupeji/12/edit?js
,
output



 类似资料:
  • 问题内容: 查找音云轨道的持续时间。 我希望创建一个秒表功能,当您单击ID 时,该功能将开始计时毫秒,以便当该功能被“单击”一定时间后,if函数将执行某些操作。就我而言,替换图像。并且该函数将在再次单击时将其自身重置。 就像= - 我该如何设置 = ?这是毫秒吗? 问题答案: 您会看到演示代码只是一个开始/停止/重置毫秒计数器。如果您想按时进行奇特的格式化,那完全取决于您。这应该足以让您入门。 这

  • 我正在尝试生成一个分辨率为微秒的时间戳。我试着用这个答案提取年/月/日等,来自C++中的std::chrono::time_point,还有这个:C++11实际系统时间(毫秒),但我不确定这样做是否正确: 该代码的输出为: 324760155[2019-09-15 10:09:13.324.324760][2019-09-15 10:09:13.324.324760]

  • 问题内容: 我正在尝试创建一个redux表单(使用redux-form),该表单可以动态创建自己的输入。我在弄清楚如何使redux- form知道已创建的新字段时遇到麻烦。是否可以动态更改redux-form在表单组件本身中传递的字段属性?我在想这个错误吗?这是我正在使用的。 问题答案: 从Redux Form 6. *开始,您可以使用来实现您想做的事情 参见下面的示例(摘自Redux文档,略有简

  • 我正试图为我的项目标准化时间戳格式,其中源以微秒精度报告。我试图找出是否有一种干净的或者最小化的方法,不需要使用手写的常量。

  • 问题内容: 我有一个JavaScript函数,该函数创建具有3行2单元格的表。 谁能告诉我如何使用我的函数创建下表(我需要针对我的情况进行此操作)? 这是下面给出的我的javascript和html代码: 问题答案: 这应该起作用(对上面的代码进行一些改动)。

  • 问题内容: 我决定使用Java重新创建Snake,但是我有些困惑。目前,我有一个正方形,用户可以使用箭头键在屏幕上移动。当您按一次LEFT时,方型会开始使用计时器向左移动。当您按任何其他已设置的键(向右,向上,向下)时,它会改变方向。我的目标是使用ArrayList容纳组成蛇的正方形。目前,我已经创建了一个ArrayList,其中仅包含一个Snake对象,如果我将第二个Snake对象添加到列表中并