Javascript 在递归函数中更新状态的正确方法(reactjs)

Javascript 在递归函数中更新状态的正确方法(reactjs),javascript,reactjs,recursion,state,Javascript,Reactjs,Recursion,State,我正在react中开发一个应用程序,它可以帮助新加入某个模式的用户以交互方式创建查询。我目前正在处理的功能如下:任何时候从查询中删除关系,从该关系访问的字段也应该删除。假设一些用户可能会运行几个“层”深的查询,列表顶部的删除将删除大量的子项,这些子项也可能有自己的子项。因此,我递归调用delete函数,检查子对象,首先对其子对象调用delete,等等,直到我们完全返回。该函数工作并命中所有正确的节点(我可以通过控制台日志验证),我遇到的问题是,由于setState是异步的,状态仅在最后一次调用时

我正在react中开发一个应用程序,它可以帮助新加入某个模式的用户以交互方式创建查询。我目前正在处理的功能如下:任何时候从查询中删除关系,从该关系访问的字段也应该删除。假设一些用户可能会运行几个“层”深的查询,列表顶部的删除将删除大量的子项,这些子项也可能有自己的子项。因此,我递归调用delete函数,检查子对象,首先对其子对象调用delete,等等,直到我们完全返回。该函数工作并命中所有正确的节点(我可以通过控制台日志验证),我遇到的问题是,由于setState是异步的,状态仅在最后一次调用时更新,并且只有最上面的节点实际从列表中过滤。我使用的代码是:

cascadeDeleteQueryFields(id) {
    //loop through the array checking for anyone with parent of id^
    this.state.queryFields.forEach((item) => {
      if (item.parent === id) {
        console.log("calling for item " + item.id);
        this.cascadeDeleteQueryFields(item.id);
      }
    });
    console.log("filtering ID : " + id);
    const queryFields = this.state.queryFields.filter((c) => c.id !== id);
    this.setState({ queryFields });
  }
(当前登录仅用于调试目的)


任何对react稍有经验的人都能推荐一种更好的方法来更新我的状态,以便捕获递归调用中的每一个更改吗?我已经研究过其他问题,但没有一个问题像我的问题一样是递归函数,因此解决方案似乎无法正常工作或效率极低。

这是我在评论中建议的方法
Descents
是一个纯函数,它提供一个集合和一个id,返回该id以及具有该id的元素(递归)后代的id,如某些对象的
parentId
字段所示

deleteQueryFields
方法调用
子体
一次,然后调用
setState
一次,结果是过滤结果中未包含的节点

const子体=(xs)=>(id)=>[
身份证件
…xs.filter(({parentId})=>parentId==id)
.map(o=>o.id)
.flatMap(子体(xs))
]
类FakeReactComponent{
建造商(州){
this.state=state
}
设置状态(新闻状态){
console.log('setState called')//应该只发生一次
this.state=Object.assign({},this.state,newState)
}
deleteQueryFields(id){
const toRemove=子体(this.state.queryFields)(id)
这是我的国家({
queryFields:this.state.queryFields.filter(({id})=>!toRemove.includes(id))
})
}
}
常量组件=新FakeReactComponent({
查询字段:[{id:1},{id:2},{id:3,parentId:2},{id:4,parentId:2},
{id:5,parentId:1},{id:6,parentId:5},{id:7,parentId:6},
{id:8},{id:9,parentId:4},{id:10,parentId:8}]
})
组件。删除查询字段(2)
console.log(component.state)

.as console wrapper{min height:100%!important;top:0}
您能否编写一个递归函数
getsubstands
来收集节点、其所有子节点、子节点等的id,然后执行类似
this.setState(this.states.filter(c=>substantids.includes(c.id))
?也就是说,首先运行所有递归计算,然后才执行
setState
调用。react中的state是不可变的,这很令人伤心,也就是说,每次设置state时都必须对对象进行深度复制,以防出现意外行为。但是,如果你选择忽略你可以考虑以下文章:你仍然会堆叠SETSATE调用,但是根据先前迭代的结果将每一个新的堆栈建立起来。@ ScTutSaaWo.我正在考虑这样做,我不知道JavaScript数组原型有一个包含函数,这是我不检查DOC的错误。(这是我第一个使用js的项目)。我认为这是这里最好的解决方案(除了给定的过滤器功能,不是吗!genderntids.includes(c.id)?)是的,当然。在这些小框中键入代码很容易出错!