vida react qué que proyecto primer practicas podemos pagina optimizar método mejores con componentes componentdidmount ciclo javascript html5-video reactjs

javascript - qué - react download



El video mostrado en el componente ReactJS no se actualiza (3)

Encontré la respuesta

La modificación dinámica de un elemento fuente y su atributo cuando el elemento ya está insertado en un elemento de video o audio no tendrá ningún efecto. Para cambiar lo que se está reproduciendo, simplemente use el atributo src en el elemento multimedia directamente, posiblemente haciendo uso del método canPlayType () para elegir entre los recursos disponibles. En general, la manipulación manual de los elementos fuente después de que el documento ha sido analizado es un enfoque innecesariamente complicado

https://html.spec.whatwg.org/multipage/embedded-content.html#the-source-element

Es bastante hacky y frágil, pero hizo el trabajo para mis casos.

(function(){ var React = require(''react''); var VideoView = React.createClass({ pickSource: function(media){ var vid = document.createElement(''video''); var maybes = media.filter(function(media){ var ext = media.split(''.'').slice(-1)[0].toUpperCase(); return (vid.canPlayType(''video/''+ext) === ''maybe''); }); var probablies = media.filter(function(media){ var ext = media.split(''.'').slice(-1)[0].toUpperCase(); return (vid.canPlayType(''video/''+ext) === ''probably''); }); var source = ''''; if (maybes.length > 0) { source = maybes[0]; } if (probablies.length > 0) { source = probablies[0]; } source = (source === '''')? '''' : ''content/''+source; return source; }, render: function(){ var video = this.props.video; var title = video.title === ''''? video.id : video.title; var src = this.pickSource(video.media); var downloadNodes = video.media.map(function(media){ var ext = media.split(''.'').slice(-1)[0].toUpperCase(); media = ''content/''+media; return ( <li><a className="greybutton" href={media}>{ext}</a></li> ) }); return ( <div className="video-container"> <video title={title} src={src} controls width="100%"></video> <h3 className="video-title">{title}</h3> <p>{video.description}</p> <div className="linkbox"> <span>Downloads:</span> <ul className="downloadlinks"> {downloadNodes} </ul> </div> </div> ) } }); module.exports = VideoView; })();

Soy nuevo en ReactJS (0.13.1) y he creado un componente en mi aplicación para mostrar video HTML5.

Parece funcionar perfectamente, pero solo para la primera selección. El video que realmente se muestra y se reproduce en la página no cambia cuando se cambia de un video a otro (cuando this.props.video cambia).

Puedo ver la actualización de los elementos <source src=''blah.mp4'' /> en el inspector de Chrome, pero el video realmente presentado en la página no cambia y continúa reproduciéndose si ya lo estaba. Lo mismo ocurre en Safari y Firefox. Todos los otros elementos se actualizan apropiadamente también.

¿Algunas ideas?

De todos modos mi componente a continuación:

(function(){ var React = require(''react''); var VideoView = React.createClass({ render: function(){ var video = this.props.video; var title = video.title === ''''? video.id : video.title; var sourceNodes = video.media.map(function(media){ media = ''content/''+media; return ( <source src={media} /> ) }); var downloadNodes = video.media.map(function(media){ var ext = media.split(''.'').slice(-1)[0].toUpperCase(); media = ''content/''+media; return (<li><a className="greybutton" href={media}>{ext}</a></li>) }); return ( <div className="video-container"> <video title={title} controls width="100%"> {sourceNodes} </video> <h3 className="video-title">{title}</h3> <p>{video.description}</p> <div className="linkbox"> <span>Downloads:</span> <ul className="downloadlinks"> {downloadNodes} </ul> </div> </div> ) } }); module.exports = VideoView; })();

ACTUALIZAR:

Para describirlo de otra manera:

Tengo una lista de enlaces con los controladores onClick que establecen los puntales del componente.

Cuando hago clic en un enlace de video ("Video Foo") por primera vez, aparece

<video title="Video Foo" controls> <source src="video-foo.mp4"/> <source src="video-foo.ogv"/> </video>

y aparece "Video Foo" y se puede reproducir.

Luego, cuando hago clic en el siguiente ("Video Bar"), las actualizaciones DOM y obtengo

<video title="Video Bar" controls> <source src="video-bar.mp4"/> <source src="video-bar.ogv"/> </video>

Sin embargo, todavía es "Video Foo" visible y puede reproducirse.

Es como una vez que el navegador ha cargado medios para un <video> , ignora cualquier cambio en los elementos <source> .


Tuve el mismo problema al hacer una lista de reproducción con videos.

Así que separé el reproductor de video a otro componente de reacción y ese componente recibió dos accesorios: contentId (video identify) y videoUrl (video URL).

También agregué una referencia a la etiqueta de video para poder administrar la etiqueta.

var Video = React.createClass({ componentWillReceiveProps (nextProps) { if (nextProps.contentId != this.props.contentId) { this.refs[''videoPlayer''].firstChild.src = this.props.videoUrl; this.refs[''videoPlayer''].load() } }, propType: { contentId: React.PropTypes.string, // this is the id of the video so you can see if they equal, if not render the component with the new url videoUrl: React.PropTypes.string, // the video url } , getDefaultProps(){ return { }; }, render() { return ( <video ref="videoPlayer" id="video" width="752" height="423"> <source src={this.props.videoUrl} type="video/mp4" /> </video> ); } }); module.exports = Video;

esto es mucho más limpio:

<Video contentId="12" videoUrl="VIDEO_URL" />


He descrito algunos enfoques para JavaScript simple aquí . Basado en eso, he encontrado soluciones para React que funcionan para mí:

  • usando el atributo src en el video mismo:

    var Video = React.createComponent({ render() { return <video src={this.props.videoUrl} />; } });

    La respuesta de Dana es una gran opción para extender esta solución.

  • usando .load() llamada en elemento de video:

    var Video = React.createComponent({ componentDidUpdate(_prevProps, _prevState) { React.findDOMNode(this.refs.video).load(); // you can add logic to check if sources have been changed }, render() { return ( <video ref="video"> {this.props.sources.map(function (srcUrl, index) { return <source key={index} src={srcUrl} />; })} </video> ); } });

UPD :

  • por supuesto, es posible agregar un atributo key único para la etiqueta <video> (por ejemplo, en función de sus fuentes), por lo que cuando cambien las fuentes también se cambiará. Pero hará que <video> se vuelva a renderizar por completo y puede causar algunos destellos de IU.

    var Video = React.createComponent({ render() { return ( <video key={this.props.videoId}> {this.props.sources.map(function (srcUrl, index) { return <source key={index} src={srcUrl} />; })} </video> ); } });