You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NextJS 13集成react-speech-recognition遇Hydration失败问题求助

NextJS 13 中 react-speech-recognition 水化错误解决方法

问题描述

在NextJS 13中使用react-speech-recognition库实现语音识别功能,复制官方示例代码后出现如下错误:

Error: Hydration failed because the initial UI does not match what was rendered on the server.

尝试过将React降级到v18.1版本、删除.next文件夹,均未解决问题。排查相关文档后,确认未直接调用window对象、也不存在标签嵌套错误,但仍无法定位问题根源。

相关代码如下:

'use client'
import 'regenerator-runtime/runtime'
import React from 'react'
import SpeechRecognition, {
  useSpeechRecognition,
} from 'react-speech-recognition'

export default function page() {
  const {
    transcript,
    listening,
    resetTranscript,
    browserSupportsSpeechRecognition,
  } = useSpeechRecognition()

  if (!browserSupportsSpeechRecognition) {
    return <span>Browser doesn't support speech recognition.</span>
  }

  return (
    <div>
      <p>Microphone: {listening ? 'on' : 'off'}</p>
      <button onClick={SpeechRecognition.startListening}>Start</button>
      <button onClick={SpeechRecognition.stopListening}>Stop</button>
      <button onClick={resetTranscript}>Reset</button>
      <p>{transcript}</p>
    </div>
  )
}

问题根源

react-speech-recognition的useSpeechRecognition钩子中,browserSupportsSpeechRecognition的值在服务端渲染时为false(服务端无浏览器环境),但在客户端浏览器支持语音识别时为true,导致服务端与客户端初始渲染的UI结构不一致,触发水化不匹配错误。

解决方案

方案1:使用useEffect延迟客户端状态初始化

通过useState设置初始状态为null,等待客户端挂载后再获取实际支持状态,确保服务端与客户端初始渲染UI一致:

'use client'
import 'regenerator-runtime/runtime'
import React, { useState, useEffect } from 'react'
import SpeechRecognition, {
  useSpeechRecognition,
} from 'react-speech-recognition'

export default function page() {
  const {
    transcript,
    listening,
    resetTranscript,
    browserSupportsSpeechRecognition,
  } = useSpeechRecognition()
  const [isClientReady, setIsClientReady] = useState(null)

  useEffect(() => {
    setIsClientReady(browserSupportsSpeechRecognition)
  }, [browserSupportsSpeechRecognition])

  if (isClientReady === null) {
    return <span>Loading...</span>
  }

  if (!isClientReady) {
    return <span>Browser doesn't support speech recognition.</span>
  }

  return (
    <div>
      <p>Microphone: {listening ? 'on' : 'off'}</p>
      <button onClick={SpeechRecognition.startListening}>Start</button>
      <button onClick={SpeechRecognition.stopListening}>Stop</button>
      <button onClick={resetTranscript}>Reset</button>
      <p>{transcript}</p>
    </div>
  )
}

方案2:动态导入库并禁用服务端渲染

使用NextJS的dynamic导入工具,仅在客户端加载react-speech-recognition相关代码:

'use client'
import 'regenerator-runtime/runtime'
import React from 'react'
import dynamic from 'next/dynamic'

// 动态导入并禁用SSR
const SpeechRecognition = dynamic(
  () => import('react-speech-recognition').then(mod => mod.default),
  { ssr: false }
)
const useSpeechRecognition = dynamic(
  () => import('react-speech-recognition').then(mod => mod.useSpeechRecognition),
  { ssr: false }
)

export default function page() {
  if (!SpeechRecognition || !useSpeechRecognition) {
    return <span>Loading...</span>
  }

  const {
    transcript,
    listening,
    resetTranscript,
    browserSupportsSpeechRecognition,
  } = useSpeechRecognition()

  if (!browserSupportsSpeechRecognition) {
    return <span>Browser doesn't support speech recognition.</span>
  }

  return (
    <div>
      <p>Microphone: {listening ? 'on' : 'off'}</p>
      <button onClick={SpeechRecognition.startListening}>Start</button>
      <button onClick={SpeechRecognition.stopListening}>Stop</button>
      <button onClick={resetTranscript}>Reset</button>
      <p>{transcript}</p>
    </div>
  )
}

内容的提问来源于stack exchange,提问作者JohnPix

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 03:45:32