我必须将一个音符与麦克风检测到的传入音符进行匹配。我正在使用 fft 来检测音高并将其与下一个最接近的音符相匹配。它以大约 10x/s 的速度触发 handleNoteEvent。问题是因为 setNote
是异步 if 语句 == true 多次,直到 setState
完成设置值,随后导致应用程序多次重新渲染。如何在使用 React 钩子时等到 setState
完成? (currentNote 被多个孩子使用)
编辑:如果我正确理解文档,带有钩子的 setState
似乎不会返回承诺或进行回调
EDIT 2:我想我必须澄清我的问题:我需要在 if 变为真后忽略传入事件,直到 setState
完成将 currentNote 设置为新的笔记对象.
function App() {
const [currentNote, setNote] = useState(new Note());
//Event handler that gets the event from the fft tuner multiple times a second
const handleNoteEvent = (fftNote) => {
if (currentNote == fftNote)) {
console.log('match');
nextNote();
}
//The problem here is the nextNote() is fired multiple times since setNote is async. How can I ignore all incoming events while setNote is not finished?
const nextNote = () => {setNote(new Note())};
...
}
答案 0 :(得分:0)
您将不得不处理另一个 setNote
中 useEffect
之后发生的事情。类似的东西:
React.useEffect(() => {
// Triggered only once when your component mounts (= componentDidMount in class component)
}, []);
React.useEffect(() => {
// It is only triggered when not changes.
// Do your things after setting notes here.
// Be careful about looping. If you set note here, you'll need to check the value as you did in your exemple to prevent updating note indefinitely
}, [note]);
一般来说,您不仅限于一个 useEffect 或一个 hook。如果需要,使用多个 useState
和 useEffect
拆分您的任务。
答案 1 :(得分:0)
好吧,在对音符更改实施 useEffect 时,我现在可以正常工作。 这似乎是一个相当肮脏的解决方案,如果有人能告诉我如何做得更干净,我将不胜感激:
const [currentNote, setNote] = useState(new Note());
var waiting = false;
const handleNoteEvent = (receivedNote) => {
if ((currentNote == receivedNote) && !waiting) {
waiting = true;
setNote(new Note());
}
};
useEffect(() => {
waiting = false;
}, [currentNote]);