• Empleos
  • Sobre nosotros
  • profesionales
    • Inicio
    • Empleos
    • Cursos y retos
  • empresas
    • Inicio
    • Publicar vacante
    • Nuestro proceso
    • Precios
    • Evaluaciones
    • Nómina
    • Blog
    • Comercial
    • Calculadora de salario

0

190
Vistas
API de Vimeo con ReactJS y Plyr

Tengo un componente React que usa el reproductor multimedia https://github.com/selz/plyr . Todo funciona bien hasta que el componente se desmonta, lo que genera un error de la API de Vimeo. Específicamente: Uncaught (in promise) TypeError: Cannot read property 'postMessage' of null .

Después de que ocurre este error, intento cargar el módulo nuevamente, fallará debido a que this.player no está undefined , pero si lo destruye y vuelve a intentarlo, se cargará. ¿Quizás React Tree está guardando la primera iteración del componente y necesito destruirlo por completo de alguna manera?

Aquí está mi componente:

 import React, {Component, PropTypes} from 'react'; import {findDOMNode} from 'react-dom'; import plyr from 'plyr'; /** * @desc Regex to retrieve the Vimeo video ID from the URL. * @type {RegExp} */ const regex = /^.*(vimeo\.com\/)((channels\/[Az]+\/)|(groups\/[Az]+\/videos\/))?([0-9]+)/g; export default class Vimeo extends Component { static propTypes = { url: PropTypes.string.isRequired, }; constructor(props) { super(props); // Use regex to get the video id from the url this.videoId = regex.exec(this.props.url); } /* |-------------------------------------------------------------------------- | Digest Cycle |-------------------------------------------------------------------------- */ /** * @desc Initiate video player. */ componentDidMount() { this.player = plyr.setup(findDOMNode(this), { controls: [], autoplay: true, loop: true, mute: true, }); this.player[0].on('ready', () => { // Mute the video if (!this.player[0].isMuted()) { this.player[0].toggleMute(); } }); } /** * @desc Destroy video player */ componentWillUnmount() { this.player[0].destroy(); } /* |-------------------------------------------------------------------------- | Render |-------------------------------------------------------------------------- */ render() { let player = null; if (typeof this.videoId !== 'undefined' && this.videoId !== null) { player = ( <div> <div data-type="vimeo" data-video-id={this.videoId} /> </div> ); } return player; } }
about 3 years ago · Santiago Trujillo
2 Respuestas
Responde la pregunta

0

Su problema está causado por la forma en que se destruye el objeto Plyr. Eche un vistazo al método _destroy() , que es lo que se expone en la API de Plyr.

https://github.com/Selz/plyr/blob/master/src/js/plyr.js#L3234

Como puede ver, en el caso de Vimeo, esta línea plyr.embed.unload().then(cleanUp); y la siguiente llamada a setTimeout en claro que _destroy no es una llamada síncrona.

Primero, plyr.embed.unload() hace una llamada a esto:

https://github.com/vimeo/player.js/blob/e0f607196f7b38e3a9891e70dda38da2731cff79/src/player.js#L440

que devuelve una Promesa . Una vez que se cumple la promesa, se ejecuta la función de cleanup en Plyr, y ahí es cuando se actualiza el DOM y se restablecen las variables. Lo que esto significa es que su componente se desmontará sin esperar a que la instancia de Plyr se restaure por completo a los valores predeterminados o se "destruya". Esto puede provocar un comportamiento inesperado si vuelve a montar el componente de inmediato.

Dentro de componentWillUnmount , le sugiero que no confíe en destroy() para actualizar el DOM y restablecer la instancia de Plyr. En su lugar, puede eliminar el elemento DOM que envuelve la inserción de video y simplemente configurar this.player en null para que la instancia de Plyr interna sea destruida y recopilada por el gc. La próxima vez que se monte su componente, los elementos DOM que contenían el video no estarán allí y su reproductor se inicializará normalmente, configurando una nueva instancia de Plyr y creando el html necesario nuevamente.

about 3 years ago · Santiago Trujillo Denunciar

0

Puede usar la API de bajo nivel de ReactTransitionGroup para obtener acceso a un nuevo ciclo de vida, componentWillLeave .

 npm i -S react-addons-transition-group

Le permitirá esperar a que el reproductor haya sido destruido antes de desmontar su componente, llamando a la devolución de llamada proporcionada. Un tiempo de espera de 200 ms debería ser suficiente, pero puede aumentarlo si quiere estar seguro.

Así que deshazte de tu componentWillUnmount y reemplázalo por algo como

 componentWillLeave(cb) { this.player[0].destroy(); setTimeout(cb, 200); }

Tendrá que envolver su componente de Vimeo en un ReactTransitionGroup , pero, por supuesto, puede crear un envoltorio si no le gusta y se reutilizará en otro lugar.


Además, es posible que desee ver react-plyr . Tiene el mismo problema que usted y es bastante nuevo, pero tiene pruebas, una estructura agradable y admite más opciones. Podría ser una buena idea unir esfuerzos para convertirla en una biblioteca genial si tienes tiempo;)

about 3 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Nuestro proceso Comercial
Legal
Términos y condiciones Política de privacidad
© 2025 PeakU Inc. All Rights Reserved.

Andres GPT

Recomiéndame algunas ofertas
Necesito ayuda