我的人数据包含动态布尔值。该值自动生成,每次都可以为true或false。
网页每5秒获取一次数据并进行渲染。如果每个人的值都是假,则播放声音。
这是代码:
import React, { Component } from 'react';
import { render } from 'react-dom';
import Sound from './Mp3';
const data = [
{
id: '1',
name: 'Peter',
value: true
},
{
id: '2',
name: 'John',
value: false
}
];
class App extends Component {
state = {
results: [],
}
componentDidMount() {
this.getData()
// get data every 5 sec
setInterval(this.getData, 5000);
}
getData = () => {
// generate random value
data[0].value = Math.random() >= 0.5;
data[1].value = Math.random() >= 0.5;
// set results state to data
this.setState({ results: data });
// condition if John or Peter value is false
if (data.some(d => d.value === false)) {
var audio = new Audio(Sound);
// play a sound
audio.play();
}
}
render() {
const { results } = this.state;
return (
<div>
{results.map(item => {
return (
<div key={item.id}>
<div>
Name: {item.name}
</div>
<div>
Value: {item.value.toString()}
</div>
<br />
</div>
)
})}
</div>
);
}
}
render(<App />, document.getElementById('root'));
这是demo
使用上面的代码,如果每个人的值都为假,则每次都会播放声音。
如何在第一次播放声音后才会出现真值?
我的意思是,如果第一个渲染的John值为false,则播放声音,如果5秒后John值仍为false,则在值返回true后再播放声音并再次更改为false。
结果我期待:
// first rendered
Name: Peter
Value: true
Name: John
Value: false // play a sound
// second (5 seconds later)
Name: Peter
Value: true
Name: John
Value: false // don't play a sound
// third (10 seconds later)
Name: Peter
Value: true
Name: John
Value: true // don't play a sound
// fourth (15 seconds later)
Name: Peter
Value: true
Name: John
Value: false // play a sound
...
答案 0 :(得分:1)
您需要跟踪每个用户在另一个对象内部的getData函数之外的先前值,然后将之前的值与其他对象中的新值进行比较。
state = {
results: []
}
const previousResults = {};
componentDidMount() {
this.getData()
// get data every 5 sec
setInterval(this.getData, 5000);
}
getData = () => {
// generate random value
data[0].value = Math.random() >= 0.5;
data[1].value = Math.random() >= 0.5;
// set results state to data
this.setState({ results: data });
// condition if user value is false & previous result for user was not false
if (data.some(d => (d.value === false) && (this.previousResults[d.id] !== false))) {
var audio = new Audio(Sound);
// play a sound
audio.play();
}
data.forEach((item) => {
this.previousResults[item.id] = item.value;
});
}
答案 1 :(得分:0)
您可以使用一种“断路器”来跟踪其状态,以及是否已启用。在绊倒之后,它会在重新启用之前等待一段时间。
以下代码演示了以下内容
true
切换到false
执行action
回调false
不会重复此操作true
,然后等待timeout
之前的时间更长,然后再次发出新的false
执行action
回调。
function TFCircuitBreaker(timeout, action){
this.state = null;
this.enabled = true;
this.valueChange = function(newValue){
if(this.enabled){
if(this.state && !newValue){
action();
this.enabled = false;
setTimeout( () => this.enabled = true,timeout);
}
}
this.state = newValue;
}
}
var cb = new TFCircuitBreaker(5000, () => console.log("Play sound"));
cb.valueChange(true);
cb.valueChange(false);
cb.valueChange(true);
cb.valueChange(false);
cb.valueChange(true);
setTimeout( () => cb.valueChange(false), 6000);
我也用类似的代码更新了你的演示,我认为你做了你想要的:https://stackblitz.com/edit/react-kmfiij?embed=1&file=index.js