2017-02-21 11 views
2

У меня есть родительский компонент, <App>:Использование setInterval в React задержки компонентов визуализации

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() это метод, который переключает active свойство <Note> «ы. Я не включаю здесь весь код, чтобы сделать его более читаемым. Проблема заключается в том, что при нажатии на <Note>, хотя его свойство active изменяется немедленно, стиль, заданный условным className «active», не отображается , пока компонент не будет повторно отображен при следующем «тике» метода setInterval , Другими словами, рендеринг кажется, как представляется, один раз каждые 1000 мс. Я бы хотел, чтобы это произошло немедленно. Я использую setInterval неправильно?

Edit:

В ответ на замечания, здесь handleClick метод (в <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>'s state, который передается до <Stave> (и который я не включил в этот вопрос для краткости).

+0

Пожалуйста, отправьте код, содержащийся в 'Staves',' Note' и 'handleClick' – Lucas

+0

Post handleClick, yes – lustoykov

+0

@Lucas Я понимаю ясность, которая принесет, но это также сделает вопрос неосуществимо длинным. Я надеюсь, хотя я мог бы, конечно, ошибаться, - что я в принципе неправильно использую setTterval. – GluePear

ответ

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

Причиной повторной визуализации является не срабатывает, потому что this.props мутирует напрямую, а не с setState. Перемещение toggleActive далее до где вы можете использовать setState.

При необходимости вы можете передать функцию в качестве опоры к компоненту ребенка и вызвать его через this.props.toggleActive()

Кроме того, не вызывая повторной визуализации, еще одна причина this.props никогда не следует мутировать непосредственно в том, что ваши изменения будут получать перезаписаны когда родитель изменяет состояние и передает реквизиты своим дочерним элементам.