当从库外触发时,React状态不是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>
);
}

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

要复制此错误,您需要:

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

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

更新:Stacklitz在这里

当您更改状态时,组件将重新呈现,即再次执行函数,但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>
);
}

triggerSomething方法中,您可以使用setCount(count => count + 1),这应该可以工作。

问题是,当您不将triggerSomething作为dep放入useEffect时,count将与初始状态相同,即0。但是,当将一个对上一个值进行计数的函数传递给setCount时,您可以避免这个问题。

最新更新