2015-08-24 16 views
2

В компоненте React я определяю, как компонент обрабатывает изменение состояния в обратном вызове до setState(). Это кажется неправильным/против конвенции о потоке. Где правильное место для определения того, как элемент должен вести себя с учетом нового состояния?Обновить компонент React при изменении состояния, используя ссылку на себя

Я предполагаю, что это метод render() или метод didMount().

В этой ситуации, мне нужно вызвать метод JS на элемент DOM:

if (this.state.play) { 
    document.querySelector(".VideoPlayer-Video").play(); 
} else { 
    document.querySelect(".VideoPlayer-Video").pause(); 
} 

Я не могу сделать это до того, как компонент оказаны. Так как &, где это должно быть сделано?

Пример Детали:

Это очень простой компонент реагировать. Он имеет элемент <video> и кнопку, которая приостанавливает или воспроизводит ее.

Состояние имеет только один атрибут «играть», который является «истинным», если видео воспроизводится или false, если видео приостановлено.

Когда нажата кнопка «играть», я переворачиваю состояние, затем выполняю запрос DOM, чтобы получить элемент видео, и вызывается метод на нем.

Это кажется нетрадиционным в React, так как я рассказываю компоненту, как реагировать на изменение состояния внутри обработчика кликов. Я хотел бы определить, как компонент реагирует на изменение состояния в другом месте, но я не знаю, где.

Где традиционное место, где можно сказать, что элемент видео воспроизводится или нет в ответ на изменение состояния? Как я могу ссылаться на элемент DOM?

Код:

var React = require('react'); 

module.exports = React.createClass({ 
    getInitialState: function(){ 
    return { 
     play: true 
    } 
    }, 
    render: function(){ 
    return <div className="VideoPlayer"> 
     <video className="VideoPlayer-Video" src="/videos/my-video.mov"></video> 
     <button className="VideoPlayer-PlayButton" onClick={this.handlePlayButtonClick}> 
     {this.state.play ? "Pause" : "Play"} 
     </button> 
    </div> 
    }, 
    handlePlayButtonClick: function(){ 
    this.setState({ 
     play: !this.state.play 
    }), function(){ 
     var video = document.querySelector(".VideoPlayer-Video"); 

     if (this.state.play) { 
     video.play(); 
     } else { 
     video.pause(); 
     } 
    } 
    } 
}); 
+0

Удивление, если это сочетание 'didMount()' и использования 'this.refs', до сих пор исследования –

ответ

4

Использование componentDidUpdate представляется подходящим.

1.Click 2. Изменение состояния -> триггер - 3. повторно вызывать Только после того, как ваш компонент установлен вызов правой функции для видео

componentDidUpdate: function() { 
    if (this.state.play) { 
     this.refs.MyVideo.play(); 
    } else { 
     this.refs.MyVideo.pause(); 
    } 
} 

Если вам нужно контролировать эти функции для самого первого рендеринг использует componentDidMount. Простой и чистый, на мой взгляд.

Edit: Я редактировал свой код, используя реф, я думаю, что это действительно правильный путь https://facebook.github.io/react/docs/more-about-refs.html

Просто поместите реф в вашем видео компонента:

<video ref="MyVideo"> </video> 

Обновлено после Комментарий к марке

+0

Это имеет смысл - но в этом коде ' видео' будет неопределенным. Каков типичный способ реагирования на получение ссылки на экземпляр этого элемента DOM? 'This.ref'? –

+1

Это выглядит хорошо, за исключением того, что вам нужно использовать 'findDOMNode (this.refs.MyVideo)', https://facebook.github.io/react/docs/working-with-the-browser.html#refs-and-finddomnode , Затем вы можете запустить методы воспроизведения и паузы, используя 'findDOMNode (this.refs.MyVideo) .play()' и 'findDOMNode (this.refs.MyVideo) .pause()' – Mark

+0

Выглядит хорошо! – Mark

2

Flux хорошее рассмотрение для долгосрочных компонентов, да это очень большой и требует некоторых отличий, а Франсуа Ричард заметил. Но все же стоит того.

Если у вас есть большой компонент, то вот несколько советов: Вы можете изменить состояние этого видео компоненты playing, только когда видео компонент получает $ события, в противном случае это не имеет смысл, так как поток в значительной степени использует nodejs EventEmitter, обратите внимание, что компоненты видео должны быть явно разделены, поэтому, расширяя свои функциональные возможности, это не повредит вашему компоненту.
Простая демонстрация repo.

+0

благодаря EVC взглянуть –

+0

Кто оставил downvote - было бы полезно знать, почему вы downvoted ответ –

+0

Вы есть проблема с мухой, вместо того, чтобы использовать классическую документально доступную прямо сейчас ловушку для ловушек, вы должны использовать эту базуку, которую я сделал. Муха на вашей кухне, поэтому вам, возможно, придется перестроить свою кухню после убийства мухи с помощью базыки, но поверьте мне, что муха будет мертва. Я думаю, что это слишком сложно, возможно, это замечательный фрагмент кода, но он советует использовать ядерное оружие против москитов. Может быть, downvoting был немного преувеличен, но я чувствовал, что парень просто пытался продвигать свой код (что, вероятно, здорово), что бы это не касалось проблемы. Вероятно, более уместно в комментарии –

1

Методы, выполняемые на DOM, должны быть вызваны в пределах componentDidUpdate, так как он вызывается, как только реакция завершила его обновления в DOM.

+0

Спасибо, Марк, так что отвечает на мой первый вопрос о том, где я должен его запускать, но как я могу ссылаться на Элемент DOM? –

Смежные вопросы