Javascript 如何在状态中每秒更新对象数组?
我试图通过将每个待办事项保存在一个对象数组中来跟踪应用程序中每个待办事项的时间。我设法让它工作,但由于我只在停止计时器时更新状态,因此组件不会显示每一秒 每秒更新状态的最简单方法是什么?我已经尝试了几天(主要是使用setInterval()),但仍然无法使它工作,因为它有点超出我的知识范围Javascript 如何在状态中每秒更新对象数组?,javascript,arrays,reactjs,react-native,Javascript,Arrays,Reactjs,React Native,我试图通过将每个待办事项保存在一个对象数组中来跟踪应用程序中每个待办事项的时间。我设法让它工作,但由于我只在停止计时器时更新状态,因此组件不会显示每一秒 每秒更新状态的最简单方法是什么?我已经尝试了几天(主要是使用setInterval()),但仍然无法使它工作,因为它有点超出我的知识范围 export default class App extends Component { constructor(props) { super(props); this.state = {
export default class App extends Component {
constructor(props) {
super(props);
this.state = {
// todos array of objects
todos: null,
// value to hold temp text input
value: '',
};
...
}
// start&stop timer + updating counters
startTimer(todoKey) {
const newTodos = this.state.todos.map(element => {
if (element.key === todoKey) {
if (element.status === "stopped") {
return { ...element, status: 'started', startTime: new Date()};
} else {
let sessionSpent = new Date() - element.startTime;
let progress = element.goal !== null ? ((element.spent === null ? sessionSpent : element.spent + sessionSpent) * 1 / element.goal) : 1;
return { ...element, status: 'stopped', startTime: null, progress: progress, spent: element.spent === null ? sessionSpent : element.spent + sessionSpent };
}
} else { return element; }
});
this.setState({
todos: newTodos
});
}
....
下面是一个简单的例子:
this.setInterval( () => {
let d = new Date();
let result = d.getHours() + d.getMinutes() / MINUTES_IN_HOUR;
this.setState({
timeLineTop: result
})
}, 1000);
经过更多的试验后,我终于成功了 如果有人有同样的问题,我会把它留在这里,但要注意:我才刚刚开始,所以我可能正在用锤子做手术 如果是这样,请提出更好的解决方案。多谢各位
export default class App extends Component {
constructor(props) {
super(props);
this.state = {
//todos array of objects
todos: null,
//value to hold temp text input
value: '',
//timer status: need to save it outside of the setInterval() loop so it doesn't stop after 1 iteration.
timerStatus: false,
//setInterval function container
interval: null,
// active timer todoKey: saving it here so I can avoid that a timer is stopped by pressing another timer's button.
activeTimer: null
};
...
}
// start&stop timer + updating counters
startTimer(todoKey) {
// first I check that there's no active timer
if (!this.state.timerStatus) {
// if no timer is active, I save the active timer's key in the state(so I can forbid activities on the timer from another timer's button)
this.setState({ activeTimer: todoKey });
// here I start the setInterval() function in a variable and save it into a variable (so later I can save it in the state)
let interval = setInterval(() => {
// looping through the array
const newTodos = this.state.todos.map(element => {
// finding the right object in the array so I can save the progress and the time spent, each second
if (element.key === todoKey) {
let sessionSpent = new Date() - element.startTime;
let progress = element.goal !== null ? ((element.spent === null ? sessionSpent : element.spent + sessionSpent) * 1 / element.goal) : 1;
return { ...element, status: 'started', startTime: new Date(), spent: element.spent + 1000, progress: progress }
} else {
return element;
}
});
this.setState({
todos: newTodos
});
}, 1000);
// setting the timerStatus as true(so I can have a trouth source outside of the loop when I need to stop it)
// saving the variable containint setInterval() in the state (so I can use clearInterval() from the else block
this.setState({ timerStatus: true, interval: interval });
console.log(this.state.timerStatus);
} else {
// checking if the pressed button is the one belonging to the active timer
if (todoKey === this.state.activeTimer) {
// saving in the state the timer's status (thus making possible for another timer to start
// clearing the setInterval() function
this.setState({ timerStatus: false, interval: clearInterval(this.state.interval) });
// looping through the array to save the current progress
const newTodos = this.state.todos.map(element => {
if (element.key === todoKey) {
let sessionSpent = new Date() - element.startTime;
let progress = element.goal !== null ? ((element.spent === null ? sessionSpent : element.spent + sessionSpent) * 1 / element.goal) : 1;
return { ...element, status: 'stopped', startTime: null, progress: progress, spent: element.spent === null ? sessionSpent : element.spent + sessionSpent };
} else {
return element;
}
}
);
// updating the state
this.setState({
todos: newTodos
});
} else {
// showing an error Toast when user tries to start another timer if there's one already active (when the check (todoKey === this.state.activeTimer) is false)
Toast.show("A timer is already running and multitasking is bad D:", Toast.LONG);
}
}
}
我在你的代码中没有看到任何试图每秒更新内容的东西。您提到了
setInterval
。你能证明这一尝试吗?虽然不完美,但我找到了解决办法。请看下面的答案。也许你能改进它。谢谢