首页 > 解决方案 > 从外部库触发时反应状态不反应

问题描述

在这里反应初学者。

我的代码

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>
  );
}

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

要复制此错误,您需要:

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

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

更新:这里的 Stackblitz

标签: javascriptreactjsreactive

解决方案


当你改变状态时,组件会重新渲染,即再次执行函数,但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>
  );
}

推荐阅读