首页 > 解决方案 > 为数组中的每个项目创建独立的秒表。根据 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>
      );
    }
}

标签: javascriptreactjsecmascript-6

解决方案


您需要为每个列表项创建两个秒表实例。我已经对您提供的链接进行了更改。我在你的列表数组中为每个对象添加了秒表,每个对象都有一个唯一的键,让 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>


推荐阅读