这里有一些代码来说明我要完成的工作
import React, { useState } from "react";
export default function App() {
const [list, setList] = useState(["a", "b", "c"]);
const [text, setText] = useState("");
let listBefore;
const addItem = () => {
listBefore = list;
setList([text, ...list]);
//simulate api call "addNewItem(newItem, confirmAdd)"
setTimeout(() => confirmAdd(false), 2000);
};
const confirmAdd = success => {
if (!success) {
setList(listBefore);
}
};
return (
<div className="App">
{list.toString()}
<input onChange={e => setText(e.target.value)} />
<button onClick={addItem}>Add</button>
</div>
);
}
目标是在我知道新列表项已成功添加到数据库之前立即更新UI。万一它失败了,我将使用“ listBefore”变量还原。我一直在试图弄清为什么它起作用,并偶然发现了闭包。我的猜测是,即使在请求成功之前可能发生许多重新渲染操作(并且listBefore被重新创建为未定义),但listBefore被“记住”在ConfirmAdd()内部,因为它在被调用时具有值。
所以我想知道1.我正确理解了如何应用闭包吗? 2.鼓励吗?
- 我是否正确理解了如何应用闭包?
您的代码中没有闭包。您的代码有效,因为listBefore
是在App
组件中全局定义的,并且代码的执行顺序也是如此。
[调用confirmAdd
时,listBefore
已被初始化并且在App
组件中全局可用,因此setList(listBefore)
有效。如果在listBefore
函数内部本地定义了addItem
,则您的代码将无法工作,因为listBefore
函数内部将无法使用confirmAdd
- 这受到鼓励吗?
使用闭包没有问题,只是您的代码没有使用闭包
下面是闭包的示例
function outer() {
const a = 'hello';
return function() {
console.log(a);
}
}
const inner = outer();
inner();
在以上代码段中,内部函数可以访问并执行a
函数后,在outer
函数事件内定义的变量outer
。