javascript - 如何同时在两个数组元素上设置状态?

标签 javascript reactjs ecmascript-6

我尝试构建一个计时器演示应用程序。我使用 setInterval 自动倒计时计时器,但我的初始状态 timer 是一个包含 2 个元素的数组,我想同时对两个计时器进行倒计时.

在我的代码中,如果我将 id 参数传递给函数(例如 1 或 2),我只能倒数一个元素,但我想一起倒数每个元素,我该怎么做这个?

This is my demo in CodePen

const timers = [
  {
    id: 1,
    time: 15,
  },
  {
    id: 2,
    time: 20,
  },
];
class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state= {
      timers,
    }

  }
  componentDidMount(){
    setInterval(() => {
      this.countDown();
    }, 1000);
  }
  countDown(id){
    const foundTimer = this.state.timers.find(timer => timer.id === id);
    foundTimer.time = foundTimer.time - 1;
    this.setState({timers: this.state.timers});
  }

  renderTimers(){
    return(
     this.state.timers.map((timer) =>{
      console.log(timer);
      return(
        <div key = {timer.id} >
          <div>{timer.time}</div>
        </div>
      )
    })
    )
  }

  render() {

    return (
      <div>
        {this.renderTimers()}
      </div>
    );
  }
}

最佳答案

使用Array#map之类的内容修改this.state.timers,将原始数组元素映射到新元素。不要直接改变状态,它是万恶之源。例如:

countDown() {
  this.setState(prevState => ({
    timers: prevState.timers.map(timer => ({
      ...timer,
      time: timer.time - 1
    }))
  }));
}

这会将每个计时器映射到一个新计时器,而不改变状态,其中新计时器保持相同的属性(通过 object spread properties ),除了它会更改每个计时器的 time 属性当前时间减 1。

如果您的环境不支持对象传播属性,请使用 Object.assign相反:

this.setState(prevState => ({
  timers: prevState.timers.map(timer =>
    Object.assign(
      {},
      timer,
      { time: timer.time - 1 }
    )
  )
}));

这将执行与上面完全相同的操作,它将属性从 timer 复制到空对象 {}(防止突变),然后覆盖 time 属性并递减它。如果您的平台不支持对象传播属性,这只是一个更详细的版本。

此外,请考虑将 timers 作为 prop 传递,而不是作为类外部的数组传递。将变量限制在尽可能小的范围内。

关于javascript - 如何同时在两个数组元素上设置状态?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45257033/

相关文章:

javascript - 找不到 Ajax 返回的元素

javascript - 找出哪个关闭按钮关闭了一个警告框

javascript - Cakephp 2.4 JSHelper 确认使用 Dialog 而不是 Javascript 确认

javascript - 当提供者重新渲染时消费者重新渲染

javascript - 这是 "React.js"的做法吗?

javascript - ES6 类构造函数不能作为普通函数调用的原因是什么?

javascript - DataTables - scrollX 导致标题被压扁

html - 我在我的代码中使用 FLEX 属性,但它不适用于 ios 7/8 设备。如何让它适用于 ios7/8?

javascript - 有没有办法用 JavaScript 访问子类中的父类(super class)变量?

javascript - 如何将 css 变量添加到用 es6 编写的 reactJS 组件中?