Here is some code to illustrate what I am trying to accomplish:
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>
);
}
The goal is to immediately update the UI before I know that the new list item was successfully added to the database. In the off chance that it failed, I revert back using my listBefore variable. I have been trying to figure out why this works and stumbled across closure. My guess is that, even though many rerenders may occur before the request succeeds (and listBefore is recreated as undefined), listBefore is "remembered" inside confirmAdd() because it had the value at the time of being called.
So I am wondering:
- Am I correct in understanding how closure is being applied?
- Is this encouraged?