React / NextJS:重复音频元件

vuktfyat  于 2023-10-18  发布在  React
关注(0)|答案(1)|浏览(108)

我正在NextJS中构建一个具有TTS功能的messenger application。为了可视化正在播放的音频波形,我使用了一个名为wavesurfer.js的第三方库
虽然实现和音频播放工作正常,但我目前的方法呈现了两个<wave>元素,其中只有一个在技术上起作用,这破坏了UI布局。

使用浏览器检查工具手动删除冗余的<wave>文件显示了sit应该正确显示的组件,但我无法确定是什么导致了另一个<wave>元素的冗余生成。

我的哪段代码导致了冗余渲染?

import Image from 'next/image';
import React, { useEffect, useRef, useState } from 'react';

import Conor from '@/public/assets/images/user.jpeg';

import PauseIcon from './PauseIcon';
import PlayIcon from './PlayIcon';

interface ChatBubbleProps {
  trackDuration: string;
  trackUrl: string;
}

function ChatBubble(props: ChatBubbleProps) {
  const [isPlaying, setIsPlaying] = useState(false);
  const waveformRef = useRef<HTMLDivElement>(null);
  const waveSurferRef = useRef<WaveSurfer | null>(null);

  useEffect(() => {
    const loadWaveSurfer = async () => {
      const { default: WaveSurfer } = await import('wavesurfer.js');
      if (props.trackUrl) {
        waveSurferRef.current = WaveSurfer.create({
          container: waveformRef.current,
          waveColor: 'white',
          progressColor: '#00000',
          cursorWidth: 0,
          cursorColor: 'transparent',
        });

        if (props.trackUrl) {
          waveSurferRef.current.load(props.trackUrl);
        }
      }
    };

    loadWaveSurfer();
  }, [props.trackUrl]);

  const handlePlayPauseClick = () => {
    setIsPlaying(!isPlaying);
    if (waveSurferRef.current) {
      waveSurferRef.current.playPause();
    }
  };

  return (
    <div className="py-4">
      <div className="flex">
        <div className="mt-auto flex h-12 w-12 -space-x-1 overflow-hidden rounded-full ">
          <Image src={User} alt="User Name" />
        </div>
        <div className="ml-4 flex h-16 w-72 items-center justify-center rounded-full bg-gradient-to-r from-rose-600 via-fuchsia-500 to-indigo-500 px-8 py-2">
          <div className="gap-8">
            <div onClick={handlePlayPauseClick}>
              {isPlaying ? <PlayIcon /> : <PauseIcon />}
            </div>
          </div>
          <div
            className="relative ml-4 w-72 items-center"
            ref={waveformRef}
          ></div>
        </div>
      </div>
    </div>
  );
}

export default ChatBubble;
8e2ybdfx

8e2ybdfx1#

通过添加if子句来修改useEffect!waveSurferRef?.current将解决您这样的问题

React.useEffect(() => {
    const loadWaveSurfer = async () => {
      const { default: WaveSurfer } = await import('wavesurfer.js')
      if (file && waveformRef?.current && !waveSurferRef.current) {
        waveSurferRef.current = WaveSurfer.create({
          container: waveformRef?.current,
          waveColor: 'white',
          progressColor: '#00000',
          cursorWidth: 0,
          cursorColor: 'transparent',
          barWidth: 3,
          barGap: 2,
          barRadius: 3,
          height: 50,
        })

        if (file) {
          waveSurferRef?.current?.load(file)
        }
      }
    }

    loadWaveSurfer()
  }, [waveSurferRef, file])

相关问题