这确实是一个竞争条件,要了解我们是如何到达那里的,我们需要完整的代码示例:
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]);
请注意,除了处理事件之外,您还需要执行此操作。这里使用卸载清理策略主要是为了启用 react 热重载。