从外部库触发时,反应状态不反应

adr*_*dev 5 javascript reactjs reactive

在这里反应初学者。

我的代码

import Head from 'next/head';
import styles from '../styles/Home.module.css';
import { useState, useEffect } from 'react';
import Mousetrap from 'mousetrap';

export default function Home() {
  const [count, setCount] = useState(0);

  const triggerSomething = () => {
    console.log(count);
  };

  useEffect(() => {
    Mousetrap.bind(['ctrl+s', 'command+s'], e => {
      e.preventDefault();
      triggerSomething();
    });

    return () => {
      Mousetrap.unbind(['ctrl+s', 'command+s']);
    };
  }, []);

  return (
    <div className={styles.container}>
      <main className={styles.main}>
        <h1 className={styles.title}>count: {count}</h1>

        <p className={styles.description}>
          <button onClick={() => setCount(count + 1)}>increment</button>
          <br />
          <br />
          <button onClick={triggerSomething}>triggerSomething</button>
        </p>
      </main>
    </div>
  );
}
Run Code Online (Sandbox Code Playgroud)

我在尝试从 触发事件时遇到问题Mousetrap。当从捕鼠器触发时,该count变量不是反应性的,但当从带有 的按钮触发时,该变量是反应性的onClick

要复制此错误,您需要:

  1. 单击增量按钮一次
  2. 单击“triggerSomething”按钮。控制台应该打印出1( 的当前状态count
  3. 按 command+s 或 ctrl+s 触发相同的方法。控制台打印出(组件加载时0的状态)。那应该打印(当前状态)。count1

我究竟做错了什么?我应该在这里使用什么模式?

更新:Stackblitz在这里

Tra*_*r69 4

当您更改状态时,组件将重新渲染,即再次执行该函数,但钩子useState这次返回更新的计数器。要在您的 中使用此更新的值MouseTrap,您必须创建一个新的处理程序(并删除旧的处理程序)。要实现此目的,只需删除调用的依赖项数组即可useEffect。然后它将使用新创建的triggerSomething函数。

import Head from 'next/head';
import styles from '../styles/Home.module.css';
import { useState, useEffect } from 'react';
import Mousetrap from 'mousetrap';

export default function Home() {
  const [count, setCount] = useState(0);

  const triggerSomething = () => {
    console.log(count);
  };

  useEffect(() => {
    Mousetrap.bind(['ctrl+s', 'command+s'], e => {
      e.preventDefault();
      triggerSomething();
    });

    return () => {
      Mousetrap.unbind(['ctrl+s', 'command+s']);
    };
  }); // Notice that I removed the dependency array

  return (
    <div className={styles.container}>
      <main className={styles.main}>
        <h1 className={styles.title}>count: {count}</h1>

        <p className={styles.description}>
          <button onClick={() => setCount(count + 1)}>increment</button>
          <br />
          <br />
          <button onClick={triggerSomething}>triggerSomething</button>
        </p>
      </main>
    </div>
  );
}
Run Code Online (Sandbox Code Playgroud)