简体   繁体   English

根据ReactJs中的计时器立即更改React表中的数据

[英]Changing data in react-table instantly based on timer in ReactJs

I have a bunch of data with timestamps(in milliseconds) and I need to replay that data in the browser based on a timer also running in the browser. 我有一堆带有时间戳(以毫秒为单位)的数据,我需要根据也在浏览器中运行的计时器在浏览器中重播该数据。 I'm using React 我正在使用React

What i've got so far is that I'm using an API call to get the data from my sql server and then I store that data in a BTree with the timestamp as a key and the data as a value. 到目前为止,我使用的是API调用以从sql服务器获取数据,然后将数据存储在BTree中,并以时间戳作为键,并将数据作为值。 The time elapsed is a state and the BTrees are states too. 经过的时间是一个状态,而BTrees也是状态。 I've tried both BTree and Hashmaps, as I initially thought the long search time in Hashmaps was my issue. 我曾经尝试过BTree和Hashmaps,因为我最初认为在Hashmaps中较长的搜索时间是我的问题。

Currently, it doesn't seem to be working and I believe its because my search and retrieval are not fast enough, even with a BTree. 目前,它似乎无法正常工作,我相信这是因为即使使用BTree,我的搜索和检索也不够快。 The value with time = 0 displays correctly, but all subsequent renders are undefined, i've attached a screen shot to the console debugger below. time = 0的值正确显示,但是所有后续渲染均未定义,我将屏幕截图附加到了下面的控制台调试器。 The numbers are the time in ms, the undefined means I don't have keys of that value, I know that. 数字是以毫秒为单位的时间,未定义表示我没有该值的键,我知道。 I'm just not sure how to "sync" them. 我只是不确定如何“同步”它们。

enter image description here 在此处输入图片说明

I have a large dataset so i'm not sure how to proceed. 我有一个很大的数据集,所以我不确定如何继续。 Is my implementation completely offbase or am I on the right track? 是我的实现完全脱离基础吗?还是我步入正轨? Is there a standardized way in doing this? 是否有标准化的方法来执行此操作?

Here is the relevant code, please let me know if there is anything else I should specify. 这是相关的代码,请告诉我是否还有其他应指定的内容。

startTimer() {
    this.setState({
      isOn: true,
      time: this.state.time,
      start: Date.now() - this.state.time
    })
    this.timer = setInterval(() => this.setState({
      time: Date.now() - this.state.start
    }), 1);
  }

  stopTimer() {
    this.setState({isOn: false})
    clearInterval(this.time)
  }

  resetTimer() {
    this.setState({time: 0, isOn: false})
  }

  handleSubmit = async e => {
    e.preventDefault();
    const response = await fetch('/api/world', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({ post: this.state.post }),
    });
    const body = await response.text();

    this.setState({ responseToPost: body });
  };

  render() {
    let start = (this.state.time == 0) ?
      <button onClick={this.startTimer}>start</button> :
      null

    let stop = (this.state.time == 0 || !this.state.isOn) ?
      null :
      <button onClick={this.stopTimer}>stop</button>

    let resume = (this.state.time == 0 || this.state.isOn) ?
      null :
      <button onClick={this.startTimer}>resume</button>

    let reset = (this.state.time == 0 || this.state.isOn) ?
      null :
      <button onClick={this.resetTimer}>reset</button>


    //DEBUG HERE
    console.log(this.state.time)
    console.log()

    var data = [{
      name: 'beams',
      aid: beamID,
      bytes: '',
      bytes: this.state.beamTree.get(this.state.time)
    },{
      name: 'cruise',
      aid: cruiseID,
      bytes: '',
      bytes: this.state.cruiseMap.get(this.state.time)
    },{
      name: 'dash',
      aid: dashID,
      bytes: '',
      bytes: this.state.dashMap.get(this.state.time)
    },{
      name: 'radio',
      aid: radioID,
      bytes: '',
      bytes: this.state.radioMap.get(this.state.time)
    },{
      name: 'tc',
      aid: tcID,
      bytes: '',
      bytes: this.state.tcMap.get(this.state.time)
    }]

    return (
      <div className="App">
          <div className="Sidebar">
            <ReactTable
              style={{"minheight" : "100%"}}
              showPagination={false}
              data={data}    
            columns={columns}     
              pageSizeOptions= {[3,9]}
            />
        </div>      
        <div>
        <h3>timer: {this.state.time}</h3>
        {start}
        {resume}
        {stop}
        {reset}
        </div>  

So, in case anyone from the future is reading this, I wound up using setInterval. 因此,以防万一将来有任何人阅读此书,我会使用setInterval结束。 Needs work but here is my App.js 需要工作,但这是我的App.js

class App extends Component {
  constructor(props){
    super(props)
    this.state = {
      response: '',
      get: '',
      post: '',
      responseToPost: '',
      responseToGet: '',
      data: {},
      message: '',
      beamMap: new HashMap(),
      cruiseMap: new HashMap(),
      dashMap: new HashMap(),
      radioMap: new HashMap(),
      tcMap: new HashMap(),
      time: 0,
      isOn: false,
      start: 0,
      end: 0,
      beamBytes: '',
      radioBytes: '',
      cruiseBytes: '',
      dashBytes: '',
      tcBytes: '',
      radioTick: 0,
      cruiseTick: 0,
      dashTick: 0,
      tcTick: 0,
      tick: 0
  }
  this.startCruiseInterval = this.startCruiseInterval.bind(this)
  this.startDashInterval = this.startDashInterval.bind(this)
  this.startTCInterval = this.startTCInterval.bind(this)
  this.startBeamInterval = this.startBeamInterval.bind(this)
  this.startRadioInterval = this.startRadioInterval.bind(this)
  this.startTimeInterval = this.startTimeInterval.bind(this)
  this.startTimer = this.startTimer.bind(this)
  this.stopTimer = this.stopTimer.bind(this)
  this.resetTimer = this.resetTimer.bind(this)
}

  //TODO
  //variable vehicle and session
  componentDidMount() {
    fetch('/session/1/1').then(
      response => response.json()
    ).then(
        json => {
        this.setState({data: json});
        var str = this.state.data

        //Store json data into the appropriate hashmap
        for(var i=0;str.length;i++){
          if(str[i].aid==beamID){
            beamHolder.set(parseInt(str[i].time),str[i].data)
            this.setState({beamMap: beamHolder})
          }else if(str[i].aid==cruiseID){
            cruiseHolder.set(parseInt(str[i].time),str[i].data)
            this.setState({cruiseMap: cruiseHolder})
          }else if(str[i].aid==dashID){
            dashHolder.set(parseInt(str[i].time),str[i].data)
            this.setState({dashMap: dashHolder})
          }else if(str[i].aid==radioID){
            radioHolder.set(parseInt(str[i].time),str[i].data)
            this.setState({radioMap: radioHolder})
          }else if(str[i].aid==tcID){
            tcHolder.set(parseInt(str[i].time),str[i].data)
            this.setState({tcMap: tcHolder})
          }
        }
      }
    );
  }

  startTimeInterval(){
    return this.setState({time: Date.now() - this.state.start})
  }

  startRadioInterval(){
    this.setState({radioBytes: this.state.radioMap.get(this.state.radioTick)})
    this.setState({radioTick: this.state.radioTick + 500})
  }

  startCruiseInterval(){
    this.setState({cruiseBytes: this.state.cruiseMap.get(this.state.cruiseTick)})
    this.setState({cruiseTick: this.state.cruiseTick + 500})
  }

  startDashInterval(){
    this.setState({dashBytes: this.state.dashMap.get(this.state.dashTick)})
    this.setState({dashTick: this.state.dashTick + 500})
  }

  startTCInterval(){
    this.setState({tcBytes: this.state.tcMap.get(this.state.tcTick)})
    this.setState({tcTick: this.state.tcTick + 500})
  }

  startBeamInterval(){
    this.setState({beamBytes: this.state.beamMap.get(this.state.tick)})
    this.setState({tick: this.state.tick + 500})
  }

  startTimer() {
    this.setState({
      isOn: true,
      time: this.state.time,
      start: Date.now() - this.state.time
    })

    this.timer = setInterval(this.startTimeInterval, 1)
    this.beamBytes = setInterval(this.startBeamInterval, 500)
    this.radioBytes = setInterval(this.startRadioInterval, 500)
    this.cruiseBytes = setInterval(this.startCruiseInterval, 500)
    this.dashBytes = setInterval(this.startDashInterval, 500)
    this.tcBytes = setInterval(this.startTCInterval, 500)
  }

  stopTimer() {
    this.setState({isOn: false})
    clearInterval(this.timer)
    clearInterval(this.beamBytes)
    clearInterval(this.radioBytes)
    clearInterval(this.cruiseBytes)
    clearInterval(this.dashBytes)
    clearInterval(this.tcBytes)
  }

  resetTimer() {
    this.setState({time: 0, isOn: false})
    this.setState({beamBytes:''})
    this.setState({radioBytes:''})
    this.setState({cruiseBytes:''})
    this.setState({dashBytes:''})
    this.setState({tcBytes:''})
    this.setState({tick:0})
    this.setState({radioTick:0})
    this.setState({cruiseTick:0})
    this.setState({dashTick:0})
    this.setState({tcTick:0})
  }

  render() {
    let start = (this.state.time == 0) ?
      <button onClick={this.startTimer}>start</button> :
      null

    let stop = (this.state.time == 0 || !this.state.isOn) ?
      null :
      <button onClick={this.stopTimer}>stop</button>

    let resume = (this.state.time == 0 || this.state.isOn) ?
      null :
      <button onClick={this.startTimer}>resume</button>

    let reset = (this.state.time == 0 || this.state.isOn) ?
      null :
      <button onClick={this.resetTimer}>reset</button>

    var data = [{
      name: 'beams',
      aid: beamID,
      bytes: this.state.beamBytes,
    },{
      name: 'cruise',
      aid: cruiseID,  
      bytes: this.state.cruiseBytes
    },{
      name: 'dash',
      aid: dashID,
      bytes: this.state.dashBytes
    },{
      name: 'radio',
      aid: radioID,
      bytes: this.state.radioBytes
    },{
      name: 'tc',
      aid: tcID,
      bytes: this.state.tcBytes
    }]

    return (
      <div className="App">
          <div className="Sidebar">
            <ReactTable
              style={{"minheight" : "100%"}}
              showPagination={false}
              data={data}    
            columns={columns}     
              pageSizeOptions= {[3,9]}
            />
        </div>      
        <div>
        <h3>timer: {this.state.time}</h3>
        {start}
        {resume}
        {stop}
        {reset}
        </div>  
      </div>
    );
  }
}

export default App;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM