2017-07-19 72 views
0

我有一個實用工具可以爲視頻生成縮略圖並將其作爲HTMLCanvasElement返回。我想渲染元素反應,就像這樣:如何在React中呈現`HTMLCanvasElement`?

render() { 
    return (
     <div className='video-thumbnail'> 
     {this.props.videoThumbnailCanvas} 
     </div> 
    ); 
} 

但是當我嘗試,我得到一個錯誤:

Error: Objects are not valid as a React child (found: [object HTMLCanvasElement]).

什麼是做到這一點的好辦法?一個想法是從componentDidMount(例如React.getDOMNode(this).appendChild(this.props.videoThumbnailCanvas))進行直接的DOM操作,但這看起來相當黑客。

+0

您是否控制效用函數?你可以讓它返回一個''JSX元素嗎? –

+0

@DannyDelott - 我確實控制它。它目前看起來像這樣: ' function getThumb(){ let canvas:HTMLCanvasElement = document.createElement('canvas'); let context = canvas.getContext('2d');如果(上下文)context.drawImage(videoElement,0,0,w,h); } return canvas; } ' 我不知道如何使用JSX元素繪製「上下文」。 – allenrabinovich

+0

我相信你不能在你的'getThumb()'中使用'document.creteElement'()' – Muhaimin

回答

0

我得到了同樣的問題,你可以通過兩種方式解決:

簡單的方法:

render() { 
    const src = this.props.videoThumbnailCanvas.toDataUrl(); 
    return (
     <div className='video-thumbnail'> 
     <img src={src} /> 
     </div> 
    ); 
} 

其他方式,我更喜歡(但個人):

onComponentDidMount() { 
    const element = document.getElementById('uniquePlaceHolderKey'); 
    element.parentNode.replaceChild(this.props.videoThumbnailCanvas, element); 
} 

render() { 
    return (
     <div className='video-thumbnail'> 
     <div id="uniquePlaceHolderKey" ></div> 
     </div> 
    ); 
} 

第二種解決方案允許您加載一個臨時元素,您將使用您自己的畫布實例進行交換。我沒有找到適當的反應解決方案來強制添加預渲染的畫布元素。 有適當的反應方法來獲取組件的元素(如this.findDomNode()),因爲它們是在組件實例上工作的,所以它們優於getElementById。

+0

所以我想使用toDataURL,但不幸的是,只有當捕獲畫布的視頻來源於允許訪問的同域或跨域時纔有效。這不能保證我的情況。如果情況並非如此,則toDataURL()會失敗,導致無法導出「受污染」(用其他域中的數據編寫)畫布的錯誤。 你的第二個建議確實需要做一個直接的DOM插入,我也可以使用實際的畫布(不帶toDataURL())。目前這是最合理的方式,但它似乎對React非常反面。 – allenrabinovich

+0

這是一個反模式。你插入的東西反應不知道。也是如此反應並不能給你一個選擇。 DataURL更高性能,並且可以使用反應組件生命週期保持活動狀態 – AndreaBogazzi

+0

oh yes第二個示例中的dataurl是複製粘貼錯誤 – AndreaBogazzi