对于上下文,我的项目使用最新的 Next.js,它使用 App Router、客户端组件和服务器组件。
我正在尝试在我的一个服务器组件中使用
await navigator.mediaDevices.getUserMedia
但它不起作用,因为我相信导航器是一个 Web API 并且该组件正在服务器上呈现。我认为这种情况是因为 navigator.mediaDevices.getUserMedia 在客户端组件中工作。我必须在这里使用服务器组件,因为客户端组件不允许异步。
我想不出一个好的方法来解决这个问题。有没有好的解决方法?
例如到目前为止我的代码:
export default async function Recorder({}: Props) {
let stream = await navigator.mediaDevices.getUserMedia({
video: true,
audio: true,
});
return <h1></h1>;
有两种方法可以解决这个问题,但在此之前我们先了解一些关于 SSR 的重要主题。我们专注于 SSR 主要是为了提供第一用户体验,因为我们在服务器上渲染 html,不需要浏览器上的任何 JS 来绘制 HTML。这为初次用户提供了非常好的体验。但是我们是否总是需要在服务器上呈现完整的 HTML?答案是这完全取决于需求,有时是 HTML 的一部分,我们可以推迟,通常我们会推迟。让我们来揭晓答案吧。
第一种方法是从浏览器获取用户代理,并使用支持所需功能的版本的浏览器的预构建 json 进行映射。
第二种方式是使用客户端组件,这是 ReactJs 的新功能,NextJs 支持。您可以通过以下方式重写此组件:
export default function Recorder({}: Props) {
const [stream, setStream] = useState<MediaStream>(null);
useEffect(() => {
navigator.mediaDevices.getUserMedia({
video: true,
audio: true,
}).then(mediaStream => {
if (stream) {
setStream(mediaStream);
}
});
}, [])
return <h1></h1>;
}
如果您使用的版本不支持此类客户端组件,那么还有另一种方法可以确保组件仅在客户端上呈现