Javascript 为什么没有反应';t更新“中的状态”;然后";答应我?

Javascript 为什么没有反应';t更新“中的状态”;然后";答应我?,javascript,reactjs,redux,async-await,es6-promise,Javascript,Reactjs,Redux,Async Await,Es6 Promise,我有一个表,每行有Delete按钮。当您删除该行时,客户端将异步发送执行API的请求。这意味着,如果您快速删除多行,您不必等待一个请求完成,就可以发送另一个删除请求。当您单击Delete按钮并发送请求时,该按钮将被禁用(在响应返回且行将消失之前) 这是处理容器中删除的函数: const [deletingTeams, setDeletingTeams] = useState([]); const handleDelete = (teamId) => { setDeleti

我有一个表,每行有
Delete
按钮。当您删除该行时,客户端将异步发送执行API的请求。这意味着,如果您快速删除多行,您不必等待一个请求完成,就可以发送另一个删除请求。当您单击
Delete
按钮并发送请求时,该按钮将被禁用(在响应返回且行将消失之前)

这是处理容器中删除的函数:

  const [deletingTeams, setDeletingTeams] = useState([]);

  const handleDelete = (teamId) => {
    setDeletingTeams([...deletingTeams, teamId]);

    deleteTeam(teamId).then(() => {    
      console.log(deletingTeams); <---- This prints EMPTY array. Why????   
      let newState = deletingTeams.filter((id) => id !== teamId);
      setDeletingTeams(newState);
    });
  };
const[deletingTeams,setDeletingTeams]=useState([]);
const handleDelete=(团队ID)=>{
设置删除团队([…删除团队,团队ID]);
deleteTeam(teamId)。然后(()=>{
console.log(deletingTeams);id!==teamId);
设置删除团队(newState);
});
};
很简单
deletingTeams
是一个数组,它保存当前正在删除的团队的ID(该API没有返回响应,删除成功)

在第3行(
setDeletingTeams([…deletingTeams,teamId]);
)中,我正在向数组中添加新的teamId,它可以正常工作。新数组正在传递到
列表
组件,并且
删除
按钮确实被禁用但是

…当响应返回时,在
中,然后
promise中,我想从数组中删除该
teamId
。问题是,
deletingTeams
数组已为空(在筛选器之前)。为什么


感谢您的解释,

状态更新是异步的-您不能保证立即看到更新状态的最新值

使用回调方法筛选和设置状态

const[deletingTeams,setDeletingTeams]=useState([]);
const handleDelete=(团队ID)=>{
设置删除团队([…删除团队,团队ID]);
删除团队(teamId)。然后(()=>{

//console.log(deletingTeams);//id!==teamId);///prev.filter((id)=>id!==teamId));//简而言之,发生这种情况的原因是因为
deletingTeams
在异步调用之前获取其值。原因很微妙

现在的情况是,当您在
then
函数中为
deleteTeam
使用
detetingTeams
时,您传入的回调函数使用了一个名为范围。那么它到底是从哪里来的呢

答案是微妙的。变量定义在第一行:
const[deletingTeams,setDeletingTeams]=useState([]);
。此时,将根据组件的当前状态(删除前当前拥有的团队)为变量分配一个值。然后,在函数中引用该值。此时,变量
deletingTeams
将添加到
Then
函数的作用域中。它是对函数外部相同变量的引用功能

好的,
deletingTeams
之所以是空数组,是因为创建
then
函数时它是空数组,不是吗?不完全是。对
deletingTeams
的任何更改都会在执行
then
函数时反映出来。但是在您的示例中,
deletingTeams
从不更改其值。您当您调用
setDeletingTeams
时,r组件的状态会发生变化,但您只需在代码块的开头查找一次状态。没有魔法会改变
deletingTeams
的值;为此,您必须再次调用
useState

deletingTeams
在每次组件重新渲染时都会被赋予一个新的值。但不幸的是,
then
函数的闭包范围只确定一次。(每次重新渲染时,您实际上会生成一个新的
then
函数,其范围为
deletingTeams
变量的渲染版本!)组件可能已重新加载,但仍使用相同的过时值调用
then

所以,总的来说,这里发生了什么:

  • deletingTeams
    在第一行中分配了一个值:
    const[deletingTeams,setDeletingTeams]=useState([]);
  • 使用
    setDeletingTeams
    更新状态,但是
    useState
    只调用一次,因此
    deletingTeams
    永远不会更新以匹配新值
  • deletingTeams
    在组件的每个新呈现上获取一个新值,但不幸的是,到那时,
    then
    函数已经绑定到一个特定的、过去的
    deletingTeams
    变量,该变量从未更新
  • 因此,当执行
    then
    块时,
    deletingTeams
    有一个过时的值

  • 那么,正确的方法是什么呢?我们可以在
    then
    函数中读取状态,以获取
    deletingTeams
    的最新值。它只是
    this.state.deletingTeams
    。以下是更多信息:

    (因为您使用的是箭头函数,
    then
    函数会自动使用与组件相同的
    this
    ,因此一切都应该正常工作。)

    因此,这应该可以做到:

    const[deletingTeams,setDeletingTeams]=useState([]);
    const handleDelete=(团队ID)=>{
    设置删除团队([…删除团队,团队ID]);
    deleteTeam(teamId)。然后(()=>{
    让newState=this.state.deletingTeams.filter((id)=>id!==teamId);
    设置删除团队(newState);
    });
    };
    

    (在这种情况下,一定要使用
    this.state.deletingTeams
    而不是再次调用
    useState
    。在嵌套函数或回调内部调用
    useState
    可能会导致错误:)

    Awesome!这很有效。接下来的问题是:我是否应该将
    setDeleting设置为相同的状态(使用以前的状态)