Is it Encouraged to Use Closures to "Save" Values within React Hooks

Viewed 65

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:

  1. Am I correct in understanding how closure is being applied?
  2. Is this encouraged?
1 Answers
  1. Yes your thought of closure is correct.
  2. It works but it is not encouraged, because this is hard to understand, and tracking when reading or debugging code. You should use useRef to sotre beforeList in this case.
Related