反应中的简单时间计数器
Simple time counter in react
我开始学习 React,我想创建一个组件来比较当前时间和开始时间并更新视图。
这是我的制作方法:
import React from 'react';
const Timer = ({ callQueuedTime }) => (
setInterval(function () {
console.log("test");
return <p>{new Date().getTime() - new Date(callQueuedTime).getTime()}</p>
}, 1000)
)
export default Timer;
在 devTools 中,console.log
每 1 秒刷新一次,但 HTML 不是。另外,我总是得到相同的值,这不是 new Date().getTime() - new Date(callQueuedTime).getTime()
的值
参考资料callQueuedTime= 2020-04-23T22:02:07.382Z
更新
我已经更新了我的组件代码:
class Timer extends React.Component {
constructor(props, context) {
super(props, context)
this.state = {
timer: 0,
}
}
componentDidMount() {
console.log(this.props)
setInterval(function () {
const time = new Date().getTime() - new Date(this.props.callQueuedTime).getTime()
this.setState({ time });
}, 1000)
}
render() {
return (
<p>{this.state.timer}</p>
);
}
}
现在,第一秒后,我收到此错误:
Cannot read property 'callQueuedTime' of undefined
你绝对可以用功能组件做到这一点。
如前所述,您无法通过 setInterval 调用 return JSX。 setInterval returns 一个用于清除的 id。
我的方法是将时间保持为状态,然后每秒更新一次效果。
import React, { useEffect, useState } from 'react';
const Timer = ({ callQueuedTime }) => {
const [time, setTime] = useState(() => new Date().getTime());
useEffect(() => {
const queuedTime = new Date(callQueuedTime).getTime();
const intervalId = setInterval(function () {
setTime(new Date().getTime() - queuedTime);
}, 1000);
return ()=>{
clearInterval(intervalId);
}
}, [callQueuedTime]);
return <p>{time}</p>;
};
export default Timer;
在 useEffect
中 return 编辑的函数是清理函数。它在下次 useEffect 运行 之前和组件卸载之前调用。
进一步阅读:
https://reactjs.org/docs/hooks-effect.html#effects-with-cleanup
https://overreacted.io/a-complete-guide-to-useeffect/
这是作为 class 组件的工作代码:
您 运行 遇到的问题是您在 setInterval 中使用了函数而不是箭头函数,因此您失去了对组件 this
的访问权限。您 运行 遇到的另一个问题是您没有在卸载时清理间隔。
import React, { Component } from "react";
export default class TimerComponent extends React.Component {
state = { time: 0 };
componentDidMount() {
this.intervalId = setInterval(() => {
const time =
new Date().getTime() - new Date(this.props.callQueuedTime).getTime();
this.setState({ time });
}, 1000);
}
componentWillUnmount(){
clearInterval(this.intervalId);
}
render() {
return <p>{this.state.time}</p>;
}
}
这是一个展示两个选项的 stackblitz:
我开始学习 React,我想创建一个组件来比较当前时间和开始时间并更新视图。
这是我的制作方法:
import React from 'react';
const Timer = ({ callQueuedTime }) => (
setInterval(function () {
console.log("test");
return <p>{new Date().getTime() - new Date(callQueuedTime).getTime()}</p>
}, 1000)
)
export default Timer;
在 devTools 中,console.log
每 1 秒刷新一次,但 HTML 不是。另外,我总是得到相同的值,这不是 new Date().getTime() - new Date(callQueuedTime).getTime()
参考资料callQueuedTime= 2020-04-23T22:02:07.382Z
更新
我已经更新了我的组件代码:
class Timer extends React.Component {
constructor(props, context) {
super(props, context)
this.state = {
timer: 0,
}
}
componentDidMount() {
console.log(this.props)
setInterval(function () {
const time = new Date().getTime() - new Date(this.props.callQueuedTime).getTime()
this.setState({ time });
}, 1000)
}
render() {
return (
<p>{this.state.timer}</p>
);
}
}
现在,第一秒后,我收到此错误:
Cannot read property 'callQueuedTime' of undefined
你绝对可以用功能组件做到这一点。
如前所述,您无法通过 setInterval 调用 return JSX。 setInterval returns 一个用于清除的 id。
我的方法是将时间保持为状态,然后每秒更新一次效果。
import React, { useEffect, useState } from 'react';
const Timer = ({ callQueuedTime }) => {
const [time, setTime] = useState(() => new Date().getTime());
useEffect(() => {
const queuedTime = new Date(callQueuedTime).getTime();
const intervalId = setInterval(function () {
setTime(new Date().getTime() - queuedTime);
}, 1000);
return ()=>{
clearInterval(intervalId);
}
}, [callQueuedTime]);
return <p>{time}</p>;
};
export default Timer;
在 useEffect
中 return 编辑的函数是清理函数。它在下次 useEffect 运行 之前和组件卸载之前调用。
进一步阅读:
https://reactjs.org/docs/hooks-effect.html#effects-with-cleanup
https://overreacted.io/a-complete-guide-to-useeffect/
这是作为 class 组件的工作代码:
您 运行 遇到的问题是您在 setInterval 中使用了函数而不是箭头函数,因此您失去了对组件 this
的访问权限。您 运行 遇到的另一个问题是您没有在卸载时清理间隔。
import React, { Component } from "react";
export default class TimerComponent extends React.Component {
state = { time: 0 };
componentDidMount() {
this.intervalId = setInterval(() => {
const time =
new Date().getTime() - new Date(this.props.callQueuedTime).getTime();
this.setState({ time });
}, 1000);
}
componentWillUnmount(){
clearInterval(this.intervalId);
}
render() {
return <p>{this.state.time}</p>;
}
}
这是一个展示两个选项的 stackblitz: