是否鼓励使用闭包在React Hook中“保存”值

问题描述 投票:2回答:2

这里有一些代码来说明我要完成的工作

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.鼓励吗?

reactjs closures react-hooks
2个回答
0
投票
  1. 是,您认为关闭是正确的。
  2. 它可以工作,但是不建议这样做,因为这很难理解,无法在读取或调试代码时进行跟踪。在这种情况下,您应该使用useRef排序beforeList。

0
投票
  1. 我是否正确理解了如何应用闭包?

您的代码中没有闭包。您的代码有效,因为listBefore是在App组件中全局定义的,并且代码的执行顺序也是如此。

[调用confirmAdd时,listBefore已被初始化并且在App组件中全局可用,因此setList(listBefore)有效。如果在listBefore函数内部本地定义了addItem,则您的代码将无法工作,因为listBefore函数内部将无法使用confirmAdd

  1. 这受到鼓励吗?

使用闭包没有问题,只是您的代码没有使用闭包

下面是闭包的示例

function outer() {
  const a = 'hello';
  
  return function() {
    console.log(a);
  }
}

const inner = outer();
inner();

在以上代码段中,内部函数可以访问并执行a函数后,在outer函数事件内定义的变量outer

© www.soinside.com 2019 - 2024. All rights reserved.