【问题标题】:Typescript error : "audioPlayer.current may be null"打字稿错误:“audioPlayer.current 可能为空”
【发布时间】:2023-01-20 19:01:12
【问题描述】:

我正在尝试学习 Typescript,为此我回到了一些组件上,将它们转换成无错误的 Typescript 文件。

我这里有一堆找不到原因的错误。我尝试了不同的选择,但无法弄清楚。

第一个在参考文献上。当我将主题与 ref.current 一起使用时,我收到错误 “可能为空”

这是组件代码:

import React, { useState, useRef, useEffect } from "react";

const AudioPlayer = () => {
  // state
  const [isPlaying, setIsPLaying] = useState(false);
  const [duration, setDuration] = useState(0);
  const [currentTime, setCurrentTime] = useState(0);
  const [currentTrack, setCurrentTrack] = useState(null);

  // references
  let audioPlayer = useRef(null); //reference to our audioplayer
  let progressBar = useRef(); //reference to our progressBar
  let animationRef = useRef(); //reference the animation

ref audioPlayer 在此处声明并在下面用于获取曲目的持续时间

  useEffect(() => {
    const seconds = Math.floor(audioPlayer.current.duration);
    console.log(audioPlayer);
    setDuration(seconds);
    progressBar.current.max = seconds;
  }, [
    audioPlayer?.current?.onloadedmetadata,
    audioPlayer?.current?.readyState,
  ]);

  const togglePlayPause = () => {
    const prevValue = isPlaying;
    setIsPLaying(!prevValue);
    if (!prevValue) {
      audioPlayer.current.play();
      animationRef.current = requestAnimationFrame(whilePlaying);
    } else {
      audioPlayer.current.pause();
      cancelAnimationFrame(animationRef.current);
    }
  };

  const whilePlaying = () => {
    progressBar.current.value = audioPlayer.current.currentTime;
    setCurrentTime(progressBar.current.value);
    animationRef.current = requestAnimationFrame(whilePlaying);
  };

  const calculateTime = (secs) => {
    const minutes = Math.floor(secs / 60);
    const returnedMinutes = minutes < 10 ? `0${minutes}` : `${minutes}`;
    const seconds = Math.floor(secs % 60);
    const returnedSeconds = seconds < 10 ? `0${seconds}` : `${seconds}`;
    return `${returnedMinutes} : ${returnedSeconds}`;
  };

  const changeRange = () => {
    audioPlayer.current.currentTime = progressBar.current.value;
    setCurrentTime(progressBar.current.value);
  };

  const changeTrack = (e) => {
    setCurrentTrack(e.target.value);
    console.log(e.target.value);
    togglePlayPause();
  };

  return (
    <>
      <div className="relative flex justify-center my-10 mx-4">
        <img src="/sphere_3D.jpg" alt="sph" width="600" />
        <p className="huit absolute">8</p>
        <input
          className="dots top-40"
          value="/piste1.mp3"
          onClick={(e) => changeTrack(e)}
        ></input>
        <input
          className="dots top-20 left-2/3"
          value="/piste2.mp3"
          onClick={(e) => changeTrack(e)}
        ></input>
      </div>
      <div>
        <audio
          ref={audioPlayer}
          src={currentTrack}
          preload="metadata"
          onCanPlay={(e) => e.target.play()}
        ></audio>
        <button className="mx-5" onClick={togglePlayPause}>
          {isPlaying ? "Pause" : "Play"}
        </button>

        {/* Current time */}
        <div>{calculateTime(currentTime)}</div>

        {/* progress bar */}
        <div>
          <input
            type="range"
            defaultValue="0"
            ref={progressBar}
            onChange={changeRange}
          />
        </div>

        {/* duration */}
        <div>{duration && !isNaN(duration) && calculateTime(duration)}</div>
      </div>
    </>
  );
};

export default AudioPlayer;

【问题讨论】:

标签: javascript reactjs typescript react-hooks typing


【解决方案1】:

向 ref 添加类型

const audioElem = useRef<HTMLAudioElement>(null);

确保在使用 current 之前检查空值:

if (audioElem.current !== null) {
    audioElem.current.focus();
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-11-07
    • 2019-09-04
    • 2022-01-08
    • 1970-01-01
    • 2021-12-16
    • 2019-05-12
    • 2017-10-12
    • 1970-01-01
    相关资源
    最近更新 更多