2017-07-22 12 views
0

我试图建立一个计时器演示程序。我用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> 
    ); 
    } 
} 

回答

4

修改this.state.timers喜欢的东西Array#map映射原始数组元素换新。不要直接改变状态,它是万恶之源。例如:

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作为支柱,而不是作为类之外的数组。尽可能限制变量的最窄范围。

+0

这是一个更好的方法! = D – G4bri3l

+0

非常感谢! :) –

+0

@Andrew Li我还有一个问题,如果我只想改变一个状态的数组(比如定时器的id是1),我怎么能不用唠叨呢? –

1

好吧首先变异状态不是一个好主意,它会导致意想不到的副作用,可以给你一个真实的头痛向下行。永不改变国家是一个好习惯。的方式来实现你想要什么,而不突变状态可以如下:

... 
countDown() { 
    const newTimers = this.state.timers.map(t => Object.assign({}, t, { time: t.time - 1})); 
    this.setState({ timers: newTimers }); 
} 
... 
相关问题