Reactjs 使用数组在单个函数中多次调用“useVal”-意外行为

Reactjs 使用数组在单个函数中多次调用“useVal”-意外行为,reactjs,react-hooks,Reactjs,React Hooks,我在一次函数调用中多次调用我的useArr函数。每次调用useArr,我都会向现有的arr函数推送一个新值。我用暂停功能错开每次通话 它不是以逐步的间隔方式呈现abcde字符串,而是简单地覆盖上一个字母。我对引擎盖下的钩子的理解不是很好,所以如果有人能提供见解,我将不胜感激 为了解释我为什么要编写这段非常规代码,我尝试模拟websocket如何与应用程序交互,如果有人想知道的话:) const-App=()=>{ 常量[arr,useArr]=useState([]) 返回( {arr} 单击

我在一次函数调用中多次调用我的
useArr
函数。每次调用
useArr
,我都会向现有的
arr
函数推送一个新值。我用
暂停
功能错开每次通话

它不是以逐步的间隔方式呈现
abcde
字符串,而是简单地覆盖上一个字母。我对引擎盖下的钩子的理解不是很好,所以如果有人能提供见解,我将不胜感激

为了解释我为什么要编写这段非常规代码,我尝试模拟websocket如何与应用程序交互,如果有人想知道的话:)

const-App=()=>{
常量[arr,useArr]=useState([])
返回(
{arr}
单击meh
)
异步函数增量(){
useArr([…arr,'a']))
等待暂停
useArr([…arr,'b']))
等待暂停
useArr([…arr,'c']))
等待暂停
useArr([…arr,'d']))
等待暂停
useArr([…arr,'e']))
等待暂停
}
异步函数暂停(){
返回新承诺(=>setTimeout(500))
}
}
导出{App}

tl;dr:你应该使用语法

这实际上更多的是理解JavaScript闭包,而不是挂钩。为了演示正在发生的事情,这里有一些基于
increment
方法的代码,但没有任何挂钩——只是普通的JavaScript

  async function increment() {
    const arr = [];
    let nextArr = undefined;
    nextArr = [...arr, 'a'];
    await pause()
    nextArr = [...arr, 'b'];
    await pause()
    nextArr = [...arr, 'c'];
    await pause()
    nextArr = [...arr, 'd'];
    await pause()
    nextArr = [...arr, 'e'];
    await pause()
  }
在该函数结束时,您希望
nextar
的值是多少<代码>['a','b','c','d','e']或
['e']
(提示:您已经在应用程序中看到了结果)

nextar
表示要传递给州设置器的内容

作为旁注,我建议您对setter变量名使用
setArr
的命名约定,而不是
useArr
useX
应该为自定义钩子保留—不用于状态设置器

您打算做的事情如下所示:

  async function increment() {
    const arr = [];
    let nextArr = undefined;
    nextArr = [...arr, 'a'];
    await pause()
    nextArr = [...nextArr, 'b'];
    await pause()
    nextArr = [...nextArr, 'c'];
    await pause()
    nextArr = [...nextArr, 'd'];
    await pause()
    nextArr = [...nextArr, 'e'];
    await pause()
  }
此代码利用上一个值创建下一个值。语法可以用来获得这种效果。使用我建议的函数更新语法和命名更改,您的
increment
函数如下所示:

  async function increment() {
    setArr(prevArr => [...prevArr, 'a'])
    await pause()
    setArr(prevArr => [...prevArr, 'b'])
    await pause()
    setArr(prevArr => [...prevArr, 'c'])
    await pause()
    setArr(prevArr => [...prevArr, 'd'])
    await pause()
    setArr(prevArr => [...prevArr, 'e'])
    await pause()
  }