如何解决在 React 中转换为函数式组件时面临的问题
这是一个非常小的两页项目,因此不会花费太多时间。
我正在尝试将 this Github 存储库从基于类的组件转换为功能组件。我非常接近,但逻辑无法正常工作。 尤其是 useState 钩子,因为值没有被保存。所以我尝试了不同的方法。
这是原始项目的现场演示的预期输出:
https://matt-eric.github.io/web-audio-fft-visualization-with-react-hooks/
这就是我所在的地方。 This is the sandbox link。
暂时忽略 The error you provided does not contain a stack trace.
错误。单击 x
并刷新小 project window
(不是您的浏览器选项卡)几次,直到音频在刷新时播放。这是因为谷歌阻止您在加载时播放音乐。
我想通过单击按钮而不是加载来播放音频。但它不起作用。
感谢任何调查它的人。
解决方法
需要一些清理工作,但这是有效的。 https://codesandbox.io/s/xenodochial-wildflower-c5b35
我真正做的就是将所有函数放在 useCallback
中,使 audioFile
成为参考,然后使 toggleAudio
函数根据当前状态播放或暂停音频.我看到的最大问题之一是您试图在单击时初始化音频,但这确实应该在安装时完成,然后当您单击时音频才开始。此外,如果您在每次点击时都进行初始化,则会导致错误,因为它已经初始化。
如果您有任何问题,请告诉我!
,使用您的沙箱,我发现缺少一些东西:
-
你需要记住你的 audoFile(因为你创建了一个新的音频并且它永远不会改变)
-
你的函数需要稳定,因此需要是react hook函数,特别是useCallback函数。
-
在演示中的 onClick 函数(开始按钮)中,您调用了 initalizeAudioAnalyzer ,但该函数已经使用您在 functionCont.jsx 上的 useEffect 进行了初始化,不需要再次初始化。一旦我删除了它,一切都奏效了。
这是现在播放音频的修复代码:
functionCont.jsx:
import React,{ useCallback,useEffect,useMemo,useState } from "react";
import VisualDemo from "./functionViz";
// import VisualDemo from "./VisualDemo";
import soundFile from "../audio/water.mp3";
const FunctionCont = () => {
const audioFile = useMemo(() => {
const audio = new Audio();
audio.crossOrigin = "anonymous";
return audio;
},[]);
const [audioData,setAudioData] = useState();
let frequencyBandArray = [...Array(25).keys()];
const initializeAudioAnalyser = useCallback(() => {
const audioContext = new AudioContext();
const source = audioContext.createMediaElementSource(audioFile);
const analyser = audioContext.createAnalyser();
audioFile.src = soundFile;
analyser.fftSize = 64;
source.connect(audioContext.destination);
source.connect(analyser);
setAudioData(analyser);
audioFile.play();
},[audioFile]);
useEffect(() => {
initializeAudioAnalyser();
},[initializeAudioAnalyser]);
const getFrequencyData = useCallback((styleAdjuster) => {
const bufferLength = audioData.frequencyBinCount;
const amplitudeArray = new Uint8Array(bufferLength);
audioData.getByteFrequencyData(amplitudeArray);
styleAdjuster(amplitudeArray);
},[audioData]);
return (
<div>
<VisualDemo
frequencyBandArray={frequencyBandArray}
getFrequencyData={getFrequencyData}
// audioData={audioData}
audioFile={audioFile}
/>
</div>
);
};
export default FunctionCont;
functionViz.jsx
import React,{ useRef,useState } from "react";
import Paper from "@material-ui/core/Paper";
import IconButton from "@material-ui/core/IconButton";
import Tooltip from "@material-ui/core/Tooltip";
import EqualizerIcon from "@material-ui/icons/Equalizer";
import { makeStyles } from "@material-ui/core/styles";
import "../stylesheets/App.scss";
const useStyles = makeStyles((theme) => ({
flexContainer: {
display: "flex",flexWrap: "wrap",justifyContent: "center",paddingTop: "25%"
}
}));
const VisualDemo = (props) => {
const classes = useStyles();
const amplitudeValues = useRef(null);
function adjustFreqBandStyle(newAmplitudeData) {
amplitudeValues.current = newAmplitudeData;
let domElements = props.frequencyBandArray.map((num) =>
document.getElementById(num)
);
for (let i = 0; i < props.frequencyBandArray.length; i++) {
let num = props.frequencyBandArray[i];
domElements[
num
].style.backgroundColor = `rgb(0,255,${amplitudeValues.current[num]})`;
domElements[num].style.height = `${amplitudeValues.current[num]}px`;
}
}
function runSpectrum() {
props.getFrequencyData(adjustFreqBandStyle);
requestAnimationFrame(runSpectrum);
}
function handleStartButtonClick() {
requestAnimationFrame(runSpectrum);
}
return (
<div>
<div>
<Tooltip title="Start" aria-label="Start" placement="right">
<IconButton
id="startButton"
onClick={handleStartButtonClick}
// disabled={!!props.audioData ? true : false}
>
<EqualizerIcon />
</IconButton>
</Tooltip>
</div>
<div className={classes.flexContainer}>
{props.frequencyBandArray.map((num) => (
<Paper
className={"frequencyBands"}
elevation={4}
id={num}
key={num}
/>
))}
</div>
</div>
);
};
export default VisualDemo;
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。