在所需节点中渲染组件

时间:2018-10-22 13:38:54

标签: reactjs

我正在使用带有opentok-react的tokbox创建视频聊天。

我正在尝试在某些节点(又称为html元素)之后添加组件。

在当前应用程序上,我正在执行类似的操作以将元素添加到需要的位置(因为否则它不会显示在我需要的“栏”上)。

// Creation of audio control
addAudioButton = (targetNode) => {
 var audioButton = document.createElement("button");
 audioButton.id = ("audio" + this.props.subId); 
 audioButton.className = "OT_edge-bar-item OT_mute OT_mode-auto"; 
 audioButton.onclick = this.toggleAudio; 
 audioButton.setAttribute("type","button");
 targetNode.insertBefore(audioButton,targetNode.children[4]);
}

要访问代码,我正在执行此操作:(以前我使用document.getElementById,但遇到了很多问题,因为有时它“不存在”。+

// Mute or unmute selected stream
toggleAudio = () => { 
let audioButton = ReactDOM.findDOMNode(this).children[0].children[6];
if(this.state.audio) { 
    audioButton.classList.add("OT_active");  // Add a class if is clicked to mute let stream = 
this.props.name.includes("Audio") ? this.props.name : this.props.name+"Audio" 
this.props.muteStream(stream); 
} 
else { 
    audioButton.classList.remove("OT_active");  // remove a class if is clicked to unmute let stream = 
this.props.name.includes("Audio") ? this.props.name : this.props.name+"Audio" 
this.props.muteStream(stream); } this.setState(prevState => ({ audio: !prevState.audio })); 
}

但是这种方式使组件不承担单一责任,因此我想为“控件”创建另一个组件,但是我也不知道该如何在需要的地方呈现该组件。

我试图这样做:

<OTSubscriber> <SubControls/> </OTSubscriber>

该软件包提供OTSubscriber,但SubControls从未呈现(我已经在html和视图中进行了检查)。

有没有办法做到这一点?也许像

render.desirednode() {
    return( SUBCONTROLS HERE);
}

谢谢。

编辑:

我想发生的事情是能够渲染这样的东西:

<OTSubscriber> <SubControls/> </OTSubscriber>

从技术上讲这是可行的,但它不会渲染任何东西。使用浏览器工具,html不会显示任何内容。借助react工具,它只能显示灰色

1 个答案:

答案 0 :(得分:0)

经过长时间的尝试,我终于有了使用Portal的解决方案。我将其发布为答案,以防其他人遇到类似问题。

使用npm软件包提供的组件的组件如下所示:

componentDidMount() {       
        this.subscriber.current.node.classList.add("stream-container")
        if(this.props.hide)
            ReactDOM.findDOMNode(this).parentElement.classList.add("Hide");

        if(this.subscriber.current && !this.state.renderControls)
            this.setState({renderControls: true});
    }

    render() {
        if(this.state.error) {
            return(
                <div>{this.state.error}</div>
            );
        }
        else {
            return(
                <Fragment>
                    <OTSubscriber
                    ref={this.subscriber}
                    session={this.props.session}
                    stream={this.props.stream}
                    properties={{
                        subscribeToAudio: this.props.audio,  // set the state of the audio of the stream
                        subscribeToVideo: this.state.video,  // set the state of the video of the stream
                        showControls: false,                 // Hide provided controls to make custom control bar
                        //restrictFrameRate: true,           // let user restrict framerate by prop in index?
                    }}                    
                    onError={this.onError}
                    />
                    {this.state.renderControls ? 
                        <SubscriberControls subscriberRef={this.subscriber} subscriberId={this.props.subscriberId}/> : null
                    }
                </Fragment>
            );            
        }
    }

如您所见,我正在使用裁判。所以在构造函数内部,我有这段代码:

this.subscriber = React.createRef();

现在,我必须在状态中添加一个新变量,因为我需要做出反应才能两次输入render方法。

  1. 用于获取OTSubscriber的引用。
  2. 呈现rendersControls组件。

现在我的SubscriberControls组件看起来像这样:

import React, { Component, Fragment } from 'react';
import ReactDOM from 'react-dom';
import './SubscriberControls.css';

export default class SubscriberControls extends Component {

    render() {
        return ReactDOM.createPortal(
            <Fragment>
                <button 
                    type="button"
                    id={"audio" + this.props.subscriberId}
                    className="OT_edge-bar-item OT_mute OT_mode-auto"
                >                
                </button>
            </Fragment>,
            this.props.subscriberRef.current.node.childNodes[0]      
        );
    }
}

通过这种方式,我实现了将SubscriberControls添加为OTSubscriber div容器的子元素。