我正在使用带有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工具,它只能显示灰色
答案 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方法。
现在我的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容器的子元素。