在一定间隔后更新反应状态

时间:2017-07-08 08:18:29

标签: javascript arrays reactjs frontend

constructor(){
    super();
    this.state={
        data : [1,2,3,4,1,2,3,4,1,3,1,4,12,2,3,2]
    };

}
componentDidMount(){setInterval(this.updateCanvas(),5000);}

updateCanvas() {
    console.log(this.props.newData);
    let data = this.state.data.slice();
    let length = data.length;
    console.log(length);
    data.push(20);
    this.setState({data:data},()=>{console.log(this.state.data);});
}

我试图每5秒将一个新值推送到状态,但状态立即改变。我怎样才能达到我想要的效果?

3 个答案:

答案 0 :(得分:3)

状态立即更改,因为您正在通过向其添加括号来调用您在此行上立即传递给setInterval的回调方法:

setInterval(this.updateCanvas(),5000);
//---------------------------^
// Adding these to function will invoke it

解决方案是将引用传递给没有括号的函数(并且它们不会立即调用它)

setInterval(this.updateCanvas,5000);

答案 1 :(得分:1)

从this.updateCanvas()中删除该括号。 即 setInterval(this.updateCanvas,5000);}

第一个将立即执行该功能,而第二个将其作为设定间隔

的函数传入

答案 2 :(得分:0)

为什么不起作用?

实际上有两个问题:

  1. 您需要将函数传递给<html> <head> <title>PARTICLES</title> <script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script> <script> $(document).ready(function(){ var d = document, $d = $(d), w = window, $w = $(w), wWidth = $w.width(), wHeight = $w.height(), credit = $('.credit > a'), particles = $('.particles'), particleCount = 0, sizes = [ 15, 20, 25, 35, 45 ], colors = [ '#f44336', '#e91e63', '#9c27b0', '#673ab7', '#3f51b5', '#2196f3', '#03a9f4', '#00bcd4', '#009688', '#4CAF50', '#8BC34A', '#CDDC39', '#FFEB3B', '#FFC107', '#FF9800', '#FF5722', '#795548', '#9E9E9E', '#607D8B', '#777777' ], mouseX = $w.width() / 2, mouseY = $w.height() / 2; function updateParticleCount () { $('.particle-count > .number').text(particleCount); }; $w .on( 'resize' , function () { wWidth = $w.width(); wHeight = $w.height(); }); $d .on( 'mousemove touchmove' , function ( event ) { event.preventDefault(); event.stopPropagation(); mouseX = event.clientX; mouseY = event.clientY; if( !!event.originalEvent.touches ) { mouseX = event.originalEvent.touches[0].clientX; mouseY = event.originalEvent.touches[0].clientY; } }) .on( 'mousedown touchstart' , function( event ) { if( event.target === credit.get(0) ){ return; } mouseX = event.clientX; mouseY = event.clientY; if( !!event.originalEvent.touches ) { mouseX = event.originalEvent.touches[0].clientX; mouseY = event.originalEvent.touches[0].clientY; } var timer = setInterval(function () { $d .one('mouseup mouseleave touchend touchcancel touchleave', function () { clearInterval( timer ); }) createParticle( event ); }, 1000 / 60) }); function createParticle ( event ) { var particle = $('<div class="particle"/>'), size = sizes[Math.floor(Math.random() * sizes.length)], color = colors[Math.floor(Math.random() * colors.length)], negative = size/2, speedHorz = Math.random() * 10, speedUp = Math.random() * 25, spinVal = 360 * Math.random(), spinSpeed = ((36 * Math.random())) * (Math.random() <=.5 ? -1 : 1), otime, time = otime = (1 + (.5 * Math.random())) * 1000, top = (mouseY - negative), left = (mouseX - negative), direction = Math.random() <=.5 ? -1 : 1 , life = 10; particle .css({ height: size + 'px', width: size + 'px', top: top + 'px', left: left + 'px', background: color, transform: 'rotate(' + spinVal + 'deg)', webkitTransform: 'rotate(' + spinVal + 'deg)' }) .appendTo( particles ); particleCount++; updateParticleCount(); var particleTimer = setInterval(function () { time = time - life; left = left - (speedHorz * direction); top = top - speedUp; speedUp = Math.min(size, speedUp - 1); spinVal = spinVal + spinSpeed; particle .css({ height: size + 'px', width: size + 'px', top: top + 'px', left: left + 'px', opacity: ((time / otime)/2) + .25, transform: 'rotate(' + spinVal + 'deg)', webkitTransform: 'rotate(' + spinVal + 'deg)' }); if( time <= 0 || left <= -size || left >= wWidth + size || top >= wHeight + size ) { particle.remove(); particleCount--; updateParticleCount(); clearInterval(particleTimer); } }, 1000 / 50); } }); </script> <style> html, body { background: #fff; width: 100%; height: 100%; overflow: hidden; cursor: default; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; font-family: 'PT Sans', sans-serif; } .title { font-size: 10vw; font-weight: 700; text-align: center; margin-top: 15%; color: #444; } .subtitle { font-size: 4vw; color: #777; font-weight: normal; text-align: center; margin-top: 0; } .credit { position: absolute; bottom: 5px; width: 100%; display: block; text-align: center; color: #777; } .credit > a { color: #777; } .particle-count { display: block; text-align: center; margin: 25px 0; } .particles > .particle { border-radius: 100%; background: transparent; position: absolute; background-size: 100% 100%; background-repeat: no-repeat; } .particles > .particle.smaller { width: 5px; height: 5px; } .particles > .particle.small { width: 10px; height: 10px; } .particles > .particle.normal { width: 15px; height: 15px; } .particles > .particle.big { width: 20px; height: 20px; } .particles > .particle.bigger { width: 25px; height: 25px; } </style> </head> <body> <h1 class='title'>PARTICLES!</h1> <h4 class='subtitle'>Click / Touch Anywhere</h4> <div class='particle-count'> <span class='number'>0</span> Particles </div> <span class='credit'> Created by <a href='https://twitter.com/Shawn_Sauce' target='_blank'>Shawn G.</a> </span> <div class='particles'></div> </body> </html> setInterval method除了函数外,它是第一个参数。使用setInterval时,将传递调用的方法setInterval(this.updateCanvas(),5000);的返回值。由于该方法没有返回任何内容(未定义),实际得到的是this.updateCanvas()

  2. 您必须将该函数绑定到组件实例的window.setInterval(undefined, 5000);。由于this方法使用updateCanvas,例如this

  3. this.setState()绑定到updateCanvas并在this中调用:

    • 传递setInterval箭头功能,并在内部调用setInveral

      updateCanvas

    • 将方法绑定到组件实例componentDidMount(){ setInterval(() => this.updateCanvas(),5000); }

      this