javascript - 为数组中的每个项目创建独立的秒表。根据 API 返回的数据设置停止时间
问题描述
创建独立的秒表。我有两个名为A
和的元素B
。当我单击A
元素时,Hello
将出现其描述和秒表。当我单击B
元素时,World
将出现其描述和秒表。我对秒表有疑问。当我单击元素A
并启动秒表时,转到元素B
然后此秒表正在运行。我的目标是,当我为该元素运行秒表时,A
它只计算该元素。当他在 element 中停止秒表A
并转到 elementB
时,在此元素中秒表将仅针对此元素计数。我在元素中停止秒表B
并转到A
元素,我将能够恢复秒表。我正在寻求一些想法来解决这个问题。我通过调用 startTime 函数发送(方法 post -> 带有开始日期的对象)。我单击停止-> 调用 stopTimer(方法发布-> 我发送带有结束日期的对象)。作为响应,该项目被压印有开始日期和结束日期,并且秒数(结束日期和开始日期之间的差)被保存在状态中。根据这些数据(开始日期、结束日期和秒),设置秒表停止的时间。如何关闭浏览器以下载此数据以设置停止时间。请给我一些建议。我会定期更正我的代码并将其插入此处。
预期效果:
单击元素A
-> 开始秒表 -> 秒表停止 -> 单击元素B
-> 开始秒表 -> 返回元素A
-> 在停止的时间恢复计时器
整个代码在这里:https ://stackblitz.com/edit/react-x9h42z
部分代码:
应用程序.js
class App extends React.Component {
constructor() {
super();
this.state = {
items: [
{
name: 'A',
description: 'Hello'
},
{
name: 'B',
description: 'World'
}
],
selectIndex: null
};
}
select = (index) => {
this.setState({
selectIndex: index
})
}
render() {
console.log(this.state.selectIndex)
return (
<div>
<ul>
{
this.state.items
.map((item, index) =>
<Item
key={index}
index={index}
item={item}
select={this.select}
items = {this.state.items}
selectIndex = {this.state.selectIndex}
/>
)
}
</ul>
<ItemDetails
items = {this.state.items}
selectIndex = {this.state.selectIndex}
/>
</div>
);
}
}
跑表
class Stopwatch extends Component {
constructor() {
super();
this.state = {
timerOn: false,
timerStart: 0,
timerTime: 0
};
}
startTimer = () => {
this.setState({
timerOn: true,
timerTime: this.state.timerTime,
timerStart: Date.now() - this.state.timerTime
});
this.timer = setInterval(() => {
this.setState({
timerTime: Date.now() - this.state.timerStart
});
}, 10);
};
stopTimer = () => {
this.setState({ timerOn: false });
clearInterval(this.timer);
};
resetTimer = () => {
this.setState({
timerStart: 0,
timerTime: 0
});
};
render() {
const { timerTime } = this.state;
let centiseconds = ("0" + (Math.floor(timerTime / 10) % 100)).slice(-2);
let seconds = ("0" + (Math.floor(timerTime / 1000) % 60)).slice(-2);
let minutes = ("0" + (Math.floor(timerTime / 60000) % 60)).slice(-2);
let hours = ("0" + Math.floor(timerTime / 3600000)).slice(-2);
return (
<div>
<div className="Stopwatch-display">
{hours} : {minutes} : {seconds} : {centiseconds}
</div>
{this.state.timerOn === false && this.state.timerTime === 0 && (
<button onClick={this.startTimer}>Start</button>
)}
{this.state.timerOn === true && (
<button onClick={this.stopTimer}>Stop</button>
)}
{this.state.timerOn === false && this.state.timerTime > 0 && (
<button onClick={this.startTimer}>Resume</button>
)}
{this.state.timerOn === false && this.state.timerTime > 0 && (
<button onClick={this.resetTimer}>Reset</button>
)}
</div>
);
}
}
解决方案
您需要为每个列表项创建两个秒表实例。我已经对您提供的链接进行了更改。我在你的列表数组中为每个对象添加了秒表,每个对象都有一个唯一的键,让 React 知道它们是不同的组件。现在,我只是用秒表渲染所有列表项,并保持每个秒表的状态,即使在切换之后我只是使用简单的无显示技术,而不是完全删除组件。检查代码,让我知道它是否适合您?
import React, { Component } from 'react';
import { render } from 'react-dom';
import './style.css';
class Item extends Component {
render() {
const selectItem = this.props.items[this.props.selectIndex]
console.log(selectItem);
return (
<li onClick={() => this.props.select(this.props.index)}>
<div>
Name:{this.props.item.name}
</div>
</li>
)
}
}
class ItemDetails extends Component {
render() {
const selectItem = this.props.items[this.props.selectIndex]
console.log(selectItem);
let content = this.props.items.map((item, index) => {
return (
<div className={this.props.selectIndex === index?'show':'hide'}>
<p>
Description:{item.description}
</p>
{item.stopWatch}
</div>
);
})
return (
<div>
{selectItem ?
content
:
null
}
</div>
)
}
}
class App extends React.Component {
constructor() {
super();
this.state = {
items: [
{
name: 'A',
description: 'Hello',
stopWatch: <Stopwatch key={1} />
},
{
name: 'B',
description: 'World',
stopWatch: <Stopwatch key={2} />
}
],
selectIndex: null
};
}
select = (index) => {
this.setState({
selectIndex: index
})
}
render() {
console.log(this.state.selectIndex)
return (
<div>
<ul>
{
this.state.items
.map((item, index) =>
<Item
key={index}
index={index}
item={item}
select={this.select}
items = {this.state.items}
selectIndex = {this.state.selectIndex}
/>
)
}
</ul>
<ItemDetails
items = {this.state.items}
selectIndex = {this.state.selectIndex}
/>
</div>
);
}
}
class Stopwatch extends Component {
constructor() {
super();
this.state = {
timerOn: false,
timerStart: 0,
timerTime: 0
};
}
startTimer = () => {
this.setState({
timerOn: true,
timerTime: this.state.timerTime,
timerStart: Date.now() - this.state.timerTime
});
this.timer = setInterval(() => {
this.setState({
timerTime: Date.now() - this.state.timerStart
});
}, 10);
};
stopTimer = () => {
this.setState({ timerOn: false });
clearInterval(this.timer);
};
resetTimer = () => {
this.setState({
timerStart: 0,
timerTime: 0
});
};
render() {
const { timerTime } = this.state;
let centiseconds = ("0" + (Math.floor(timerTime / 10) % 100)).slice(-2);
let seconds = ("0" + (Math.floor(timerTime / 1000) % 60)).slice(-2);
let minutes = ("0" + (Math.floor(timerTime / 60000) % 60)).slice(-2);
let hours = ("0" + Math.floor(timerTime / 3600000)).slice(-2);
return (
<div>
<div className="Stopwatch-display">
{hours} : {minutes} : {seconds} : {centiseconds}
</div>
{this.state.timerOn === false && this.state.timerTime === 0 && (
<button onClick={this.startTimer}>Start</button>
)}
{this.state.timerOn === true && (
<button onClick={this.stopTimer}>Stop</button>
)}
{this.state.timerOn === false && this.state.timerTime > 0 && (
<button onClick={this.startTimer}>Resume</button>
)}
{this.state.timerOn === false && this.state.timerTime > 0 && (
<button onClick={this.resetTimer}>Reset</button>
)}
</div>
);
}
}
render(<App />, document.getElementById('root'));
h1, p {
font-family: Lato;
}
.show {
display: block;
}
.hide {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>
推荐阅读
- vue.js - 保持用户从 SPA (websanova) 之外的 Vue.js SPA 登录
- css - CSS 相对位置对 DOM 渲染有性能影响吗?
- android - Firebase Crashlytics 与 Fabric Crashlytics
- java - Is there a modern way to run java applications in browser?
- robotframework - 如何通过 Robot 框架在 unix 中顺序执行多个命令?
- python - 为 ndb.tasklets 输入注释
- ajax - wp_send_json* functions do a weird float values conversion
- java - 多个 JComboBox 侦听器
- python - Getting the name of a class which has a meta class
- sql - How to retrieve all user tables, corresponding columns and data types in SQL Server?