Redux组件和用于定时器逻辑的useEffect



所以,我有一个功能组件,有一对文本框(名称和计时器I/p框显示)和开始/停止按钮。

I want that;

  1. 当单击"开始"时,计时器框应计数并显示经过的秒数。
  2. 当单击Stop时,保存名称和时间以减少存储,计时器i/p框返回零。(名称/计时器的保存值作为另一个组件的一部分显示在下面)
  3. 当焦点在计时器框上时,计时器应该停止/暂停
  4. 当我们对焦/模糊计时器框时,计时器应该从该点恢复。

我已经在下面的链接中添加了我的代码到沙箱。https://codesandbox.io/s/crisil-tp7pv?file=/src/TestComponent.js

部分相关代码也在下面突出显示。从本质上讲,我想知道,如果我使用useEffect来更新计时器框?有什么改进方法的建议吗?

export const TestComponent = (props) => {
  const [task, setTask] = useState({ id: 0, taskName: "", timeField: 0 });
  const [stopTimerEvt, setStopTimerEvt] = useState(true);
  //var timerId;
  useEffect(() => {
    var seconds = 0;
    var interval;
    if (stopTimerEvt === false) {
      interval = setInterval(function () {
        setTask((prevState) => {
          return { ...prevState, timeField: seconds++ };
        });
      }, 1000);
    }
    return () => clearInterval(interval);
  }, [stopTimerEvt]);
  const startTimer = () => {
    setStopTimerEvt(false);
    /*
    timerId = setInterval(function () {
      setTask((prevState) => {
        return { ...prevState, timeField: seconds++ };
      });
    }, 1000);
    */
  };
  const stopTimer = () => {
    //clearInterval(timerId);
    setStopTimerEvt(true);
    props.saveTask(task);
    setTask((prevState) => {
      return { ...prevState, timeField: 0 };
    });
  };
  const handleChange = (e) => {
    setTask((prevState) => ({
      ...prevState,
      [e.target.id]: e.target.value
    }));
  };
  return (
    <main>
      <input
        type="text"
        id="taskName"
        value={task.taskName}
        onChange={handleChange}
      />
      <input
        type="number"
        id="timeField"
        value={task.timeField}
        onChange={handleChange}
      />
      <button id="start" onClick={startTimer}>
        Start
      </button>
      <button id="stop" onClick={stopTimer}>
        Stop
      </button>
    </main>
  );
};
export default connect(null, { saveTask })(TestComponent);

以下是您需要在TestComponent中进行的一些更改:

export const TestComponentNew = (props) => {
  const [task, setTask] = useState({ taskName: "", timeField: 0 });
  const timer = useRef();
  useEffect(() => {
    return () => stopTimer();
  }, []);
  const startTimer = () => {
    timer.current = setInterval(function () {
      setTask((v) => ({ ...v, timeField: +v.timeField + 1 }));
    }, 1000);
  };
  const stopTimer = () => {
    clearInterval(timer.current);
    timer.current = null;
    props.saveTask(task);
    setTask({ taskName: "", timeField: 0 });
  };
  const handleChange = (e) => {
    setTask((prevState) => ({
      ...prevState,
      [e.target.id]: e.target.value
    }));
  };
  return (
    <main>
      <input
        type="text"
        id="taskName"
        value={task.taskName}
        onChange={handleChange}
        placeholder="task name"
      />
      <input
        type="number"
        id="timeField"
        value={task.timeField}
        onChange={handleChange}
      />
      <button id="start" onClick={startTimer}>
        Start
      </button>
      <button id="stop" onClick={stopTimer}>
        Stop
      </button>
    </main>
  );
};

下面是演示:https://codesandbox.io/s/crisil-forked-pfrb3?file=/src/TestComponentNew.js

EDITED

export const TestComponentNew = (props) => {
  const [task, setTask] = useState({ taskName: "", timeField: 0 });
  const timer = useRef();
  useEffect(() => {
    return () => stopTimer();
  }, []);
  const startTimer = () => {
    timer.current = setInterval(function () {
      setTask((v) => ({ ...v, timeField: +v.timeField + 1 }));
    }, 1000);
  };
  const stopTimer = () => {
    clearInterval(timer.current);
    timer.current = null;
    props.saveTask(task);
    setTask({ taskName: "", timeField: 0 });
  };
  const handleChange = (e) => {
    setTask((prevState) => ({
      ...prevState,
      [e.target.id]: e.target.value
    }));
  };
  const handlePause = () => {
    clearInterval(timer.current);
  };
  return (
    <main>
      <input
        type="text"
        id="taskName"
        value={task.taskName}
        onChange={handleChange}
        placeholder="task name"
      />
      <input
        type="number"
        id="timeField"
        value={task.timeField}
        onChange={handleChange}
        onFocus={handlePause}
        onBlur={startTimer}
      />
      <button id="start" onClick={startTimer}>
        Start
      </button>
      <button id="stop" onClick={stopTimer}>
        Stop
      </button>
    </main>
  );
};

相关内容

  • 没有找到相关文章

最新更新