反应忽略事件,直到 setState 完成设置 usestate

时间:2021-02-13 16:56:20

标签: javascript reactjs react-native

我必须将一个音符与麦克风检测到的传入音符进行匹配。我正在使用 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())};
...
}

2 个答案:

答案 0 :(得分:0)

您将不得不处理另一个 setNoteuseEffect 之后发生的事情。类似的东西:

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。如果需要,使用多个 useStateuseEffect 拆分您的任务。

答案 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]);