San*_*ord 10 reactjs react-hooks
我正在使用以下组件在我的应用程序中提交评论:
const App = () => {
const [text, setText] = React.useState("");
const send = React.useCallback(() => {
setText("");
console.log("sending", text);
}, [text]);
React.useEffect(() => {
const handler = e => {
switch (e.keyCode) {
case 13: // enter
if (e.shiftKey) {
e.preventDefault();
send();
}
break;
}
}
document.addEventListener("keydown", handler);
return () => document.removeEventListener("keydown", handler);
}, []);
return <div className="App">
<textarea
className="App__text"
value={text}
onChange={e => {
setText(e.target.value);
}} />
<button className="App__send" onClick={send}>send</button>
</div>;
};
Run Code Online (Sandbox Code Playgroud)
这是一个简单的文本字段和按钮。当按下按钮或 Shift-Enter 时,文本字段中的文本将被发送到服务器(这里只是console.log它)。
该按钮工作正常 - 输入"hello world"(或其他)按下按钮,控制台会显示hello world。
但是,Shift-Enter 始终打印空字符串。
我想我是误会了useCallback。据我了解,useCallback包装了你的功能。当其中一个依赖项发生变化时,React 会在不更改包装器函数的情况下替换您的函数,因此无论在何处使用它,它仍然是最新的引用。鉴于被send调用的useEffect似乎具有textin 范围内的初始值,但 the 中使用的值onClick具有button最新值,我的假设似乎不正确。
我也尝试添加为但text的依赖项useEffect
如何将send函数的当前版本保留在另一个回调中?
Ant*_*jac 10
您缺少send依赖项,请查看此更新的代码:
React.useEffect(() => {
const handler = e => {
switch (e.keyCode) {
case 13: // enter
if (e.shiftKey) {
e.preventDefault();
send(); // This will always be called an older version, instead of updated one
}
break;
}
}
document.addEventListener("keydown", handler);
return () => document.removeEventListener("keydown", handler);
}, [send]); // You need to put send here, since it is part of this component, and needs to be updated
Run Code Online (Sandbox Code Playgroud)
它与它一起工作的原因是因为send函数也被记忆了:
const send = React.useCallback(() => {
setText("");
console.log("sending", text);
}, [text]);
Run Code Online (Sandbox Code Playgroud)
因此您需要确保更新到较新的版本及其较新的文本(这从未发生过,这就是为什么您的 SHIFT+ENTER 中没有文本)
编辑:经过进一步调查,在我看来,最大的问题是不同步文本和侦听器处理程序。
我已经修改了代码以使其工作,方法是完全删除侦听器,并onKeyDown直接在文本区域上使用 prop 。看看这个工作代码笔:
https://codepen.io/antonioerda/pen/zYqYWgx
| 归档时间: |
|
| 查看次数: |
17272 次 |
| 最近记录: |