这确实是一个竞争条件,要了解我们是如何到达那里的,我们需要完整的代码示例:
useEffect(() => {
if (!localParticipant) {
return;
}
for (const localTrack of localTracks) {
if (localTrack.kind === 'video') {
localParticipant.publishTrack(localTrack, {
priority: 'low',
});
} else {
localParticipant.publishTrack(localTrack, {
priority: 'standard',
});
}
}
return () => {
localParticipant.audioTracks.forEach((publication) => {
publication.unpublish();
});
localParticipant.videoTracks.forEach((publication) => {
publication.unpublish();
});
};
}, [localParticipant, localTracks]);
这里发生的是,每次localParticipant
或localTracks
更改时,我们都会做两件事:
- 我们通过取消设置任何现有的音频/视频轨道进行清理
- 我们绑定新曲目
不知何故,清理逻辑导致该localParticipant.publishTrack
方法进入错误状态(“轨道名称重复”)publishTrack
在unpublish
.
解决方法是简单地将unpublish
逻辑移动到不依赖于localTracks
.
useEffect(() => {
if (!localParticipant) {
return;
}
return () => {
localParticipant.audioTracks.forEach((publication) => {
publication.unpublish();
});
localParticipant.videoTracks.forEach((publication) => {
publication.unpublish();
});
};
}, [localParticipant]);
useEffect(() => {
if (!localParticipant) {
return;
}
for (const localTrack of localTracks) {
if (localTrack.kind === 'video') {
localParticipant.publishTrack(localTrack, {
priority: 'low',
});
} else {
localParticipant.publishTrack(localTrack, {
priority: 'standard',
});
}
}
}, [localParticipant, localTracks]);
请注意,除了处理事件之外,您还需要执行此操作。卸载清理策略在这里主要用于启用反应热重载。