2017-02-21 104 views
2

我有一個父組件,<App>使用的setInterval在陣營延遲部件渲染

constructor() { 
    super();    
    this.state = { 
     transporterPos: 0 
    } 
    this.tick = this.tick.bind(this); 
} 

componentDidMount() { 
    this.timerId = setInterval(() => this.tick(), 1000); 
} 

componentWillUnmount() { 
    clearInterval(this.timerId); 
} 

tick() { 
    let transporterPos = this.state.transporterPos; 
    transporterPos++; 
    if (transporterPos > 7) { 
     transporterPos = 0; 
    } 
    this.setState({ transporterPos: transporterPos }); 
} 

render() { 
    return (
     <div> 
      <Staves transporterPos={this.state.transporterPos}/> 
     </div> 
    ); 
} 

<Staves>部件包含幾個<Stave>組件,其中的每一個包含幾個<Note>組件。每個<Note>組分與className條件注射在其active屬性是true

<div className="noteContainer" onClick={this.handleClick}> 
    <div className={"note" + (this.props.active ? ' active' : '')}></div> 
</div> 

handleClick()是切換一個<Note>active屬性的方法。我沒有在這裏包含所有代碼,以使其更具可讀性。問題是在<Note>點擊時,儘管其active屬性更改立即,直至分量在setInterval方法的下一個「滴答」重新呈現由「主動」的條件className給出的風格是不可見的。換句話說,渲染似乎每1000毫秒只發生一次。我希望它立即發生。我使用setInterval錯了嗎?

編輯:

在迴應評論,這裏是​​方法(在<Note>):

handleClick() { 
    this.props.toggleActive(this.props.pos); 
} 

這就要求toggleActive<Stave>

toggleActive(pos) { 
    this.props.notes[pos].active = !this.props.notes[pos].active; 
} 

props.notes這裏部分<App>state,它傳遞給<Stave>(爲簡潔起見,我沒有在這個問題中包含這個)。

+0

請發佈代碼''Staves','Note'和'handleClick' – Lucas

+0

Post handleClick,是 – lustoykov

+0

@Lucas我明白會帶來的清晰度,但它也會使問題變得不可行。我希望 - 雖然我當然可能是錯的 - 我原則上濫用'setInterval'。 – GluePear

回答

1
toggleActive(pos) { 
    this.props.notes[pos].active = !this.props.notes[pos].active; 
} 

之所以重新繪製未被觸發是因爲this.propssetState突變,而不是直接的。將toggleActive進一步移動到您可以使用的地方setState

如果需要,可以通過功能爲道具到子組件,並通過this.props.toggleActive()

調用它除了不觸發重新繪製,另一個原因this.props永遠不應該直接突變是因爲您的更改將被覆蓋每當家長改變狀態並將道具傳遞給其子女時。