从外部库触发时反应状态不反应
React state not reactive when triggered from outside library
这里是 React 初学者。
我的代码
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
的当前状态)
- 按 command+s 或 ctrl+s 触发相同的方法。控制台打印出
0
(组件加载时count
的状态)。 那应该打印 1
(当前状态)。
我做错了什么?我应该在这里使用什么模式?
更新:
Stackblitz here
当你改变状态时,组件被重新渲染,即函数被再次执行,但是 useState
hook returns 这次更新了计数器。要在 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
作为 useEffect
中的 dep 时,计数将与初始状态相同,即 0。但是当传递一个函数依赖于 setCount
的先前值,您将避免此问题。
这里是 React 初学者。
我的代码
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
的当前状态) - 按 command+s 或 ctrl+s 触发相同的方法。控制台打印出
0
(组件加载时count
的状态)。 那应该打印1
(当前状态)。
我做错了什么?我应该在这里使用什么模式?
更新: Stackblitz here
当你改变状态时,组件被重新渲染,即函数被再次执行,但是 useState
hook returns 这次更新了计数器。要在 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
作为 useEffect
中的 dep 时,计数将与初始状态相同,即 0。但是当传递一个函数依赖于 setCount
的先前值,您将避免此问题。