Javascript 在React组件中重新附加DOM元素
我面临的情况是需要从DOM中完全删除一个元素并重新连接它。更具体地说,当更改视频元素的src时,Airplay功能中的错误会导致缺少曲目信息:Javascript 在React组件中重新附加DOM元素,javascript,reactjs,Javascript,Reactjs,我面临的情况是需要从DOM中完全删除一个元素并重新连接它。更具体地说,当更改视频元素的src时,Airplay功能中的错误会导致缺少曲目信息: 更改videoelement的src属性并开始在Apple TV上播放 现在将源切换到其他视频 曲目信息(音频、文本)丢失 我找到了一个解决方法,需要从DOM中删除视频元素,创建一个新的元素,然后将其重新添加到DOM中。使用react执行此操作的最佳方法是什么?我尝试设置我的子组件的键属性,但这似乎不起作用。以下是代码的摘录: class Contain
class Container extends Component {
render() {
<Video key={this.videoElementKey} />
}
}
class Video extends Component {
render() {
return (
<video id="vid" className="video-elem" playsInline />
);
componentDidMount() {
console.log("componentDidMount");
}
}
类容器扩展组件{
render(){
}
}
类视频扩展组件{
render(){
返回(
);
componentDidMount(){
log(“componentDidMount”);
}
}
组件会像我预期的那样重新安装。这是否意味着videoelement会被删除并重新读取?此外,组件的ref属性是否已刷新?我不确定您试图完成什么,但您可能需要检查。它允许您实际卸载自定义组件和ref然后,你可以再次添加你的组件 您可以执行以下操作:
ReactDOM.unmountComponentAtNode(document.getElementById(yourNodeID));
很抱歉,这不是一个非常完整的答案,但是如果不了解更多的实现,这很难。无论如何,它可能为您指明了正确的方向。要强制卸载元素,您可以创建两个扩展视频元素的元素,并在使用条件ren更新
src
时在它们之间切换因此,每次更改时,其中一个视频组件将被卸载,另一个将被安装到它的位置
下面是使用一组视频src
s的示例:
import React, { Component } from 'react';
const videos = [
'https://img-9gag-fun.9cache.com/photo/a9KrqE1_460sv.mp4',
'https://img-9gag-fun.9cache.com/photo/a3Qq4PN_460sv.mp4',
'https://img-9gag-fun.9cache.com/photo/aE2Yq9O_460sv.mp4'
];
class App extends Component {
constructor(props) {
super(props);
this.onNext = this.onNext.bind(this);
this.state = {
current: 0
}
}
onNext = event => {
this.setState((prevState) => ({
// using modulo to stay within the length of videos array
current: (prevState.current + 1) % videos.length
}));
};
render() {
return (
<div className="App">
// switching between two video components if index is odd/even
{ this.state.current % 2 === 1
? <One current={this.state.current} />
: <Two current={this.state.current} /> }
<hr />
<button onClick={this.onNext}>Next video</button>
</div>
);
}
}
class Video extends Component {
render() {
return (
<video key={'key-'+this.props.current} id="vid" className="video-elem" playsInline src={videos[this.props.current]} />
);
}
componentDidMount() {
console.log("componentDidMount");
}
componentWillUnmount() {
console.log("componentWillUnmount");
}
}
class One extends Video {}
class Two extends Video {}
export default App;
import React,{Component}来自'React';
常量视频=[
'https://img-9gag-fun.9cache.com/photo/a9KrqE1_460sv.mp4',
'https://img-9gag-fun.9cache.com/photo/a3Qq4PN_460sv.mp4',
'https://img-9gag-fun.9cache.com/photo/aE2Yq9O_460sv.mp4'
];
类应用程序扩展组件{
建造师(道具){
超级(道具);
this.onNext=this.onNext.bind(this);
此.state={
电流:0
}
}
onNext=事件=>{
this.setState((prevState)=>({
//使用模保持在视频数组长度内
当前:(prevState.current+1)%videos.length
}));
};
render(){
返回(
//如果索引为奇数/偶数,则在两个视频组件之间切换
{this.state.current%2==1
?
: }
下一个视频
);
}
}
类视频扩展组件{
render(){
返回(
);
}
componentDidMount(){
log(“componentDidMount”);
}
组件将卸载(){
log(“componentWillUnmount”);
}
}
第一类扩展了视频{}
第二类扩展了视频{}
导出默认应用程序;
运行。是的,
键
应该会有帮助。通过您的示例,很难意识到什么是错的,因为
与
没有任何共同之处。在您的情况下,因为您需要在src
更改后重新安装
,我相信您可以使用键={this.props.urltovide}src={this.props.urltovide}
只需将该
用作一个组件,并通过更改道具进行渲染。这样会更容易进行跟踪。很抱歉,孩子的命名错误。我修复了这个问题,视频组件现在在容器组件中被引用。但是,重新安装视频组件似乎不会从容器中删除HTML5视频元素由于上述Airplay实现中的错误,这正是我所需要的。在普通JavaScript中,document.body.removeChild(document.getElementById('vid'));Hey@DanielSilhavy查看我下面的答案,它通过react从DOM中删除组件谢谢你的回答,仍然不确定这是否是我需要的。更准确地说,我需要能够真正从DOM中删除元素。我希望react在重新安装组件时会这样做,但显然这不是ca我有点惊讶,这是如此棘手。所以在我的例子中,没有反应,我只是这样做:document.body.removeChild(video);
视频是document.getElementById(“video”)
好的,如果您想从DOM中删除HTML元素(节点),那么您需要执行类似于您在上面的评论中发布的操作。React不会删除元素本身,因为它需要一些节点来(重新)删除挂载组件…所以,是的,我之前的答案只有在移除元素/节点并且由于某种原因连接到它的组件没有被移除时才有用(在这种情况下,即使你看不到它,它也会留在内存中)。