在这里反应初学者。
我的代码
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
从按钮触发时是反应性的。
要复制此错误,您需要:
- 单击增量按钮一次
- 单击triggerSomething按钮。控制台应打印出
1
(count
的当前状态) - 按下命令+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
时,您可以避免这个问题。