Arrays 正在从React中的状态数组中删除项

Arrays 正在从React中的状态数组中删除项,arrays,reactjs,use-state,Arrays,Reactjs,Use State,我在React中有一个名为Spec的函数组件,它有一个带有下面接口的块列表规范维护用户可以添加、编辑或删除的块列表 问题:删除操作未按预期工作 如果只有一个块,那么它什么也不做,函数中的第一个console.log()返回一个空数组(长度应为1),第二个console.log()返回一个长度为1的数组(应为空) 如果数组中有两个以上的块,则无论我删除哪个索引,都会删除数组的最后(n-1)元素 有人能看出我做错了什么吗 //types.d.ts interface Block extends A

我在React中有一个名为
Spec
的函数组件,它有一个带有下面接口的块列表<代码>规范维护用户可以添加、编辑或删除的块列表

问题:删除操作未按预期工作

  • 如果只有一个块,那么它什么也不做,函数中的第一个
    console.log()
    返回一个空数组(长度应为1),第二个
    console.log()
    返回一个长度为1的数组(应为空)
  • 如果数组中有两个以上的块,则无论我删除哪个
    索引
    ,都会删除数组的最后
    (n-1)
    元素
  • 有人能看出我做错了什么吗

    //types.d.ts
    
    interface Block extends Array {
      type: string,
      block: StoryBlock | MarkdownBlock
    }
    
    interface StoryBlock {
      title: string,
      description: string,
      visibility: boolean,
      status: string,
    }
    
    interface MarkdownBlock {
      title: string,
      description: string,
      visibility: boolean,
    }
    
    const Spec:React.FC=(道具)=>{
    const[blocks,setblock]=useState([]);
    ...
    const addBlock=(类型:string)=>{
    让区块种子;
    开关(类型){
    案例“故事”:
    blockSeed=emptyStoryData;
    打破
    “降价”一案:
    blockSeed=emptyMarkdownText
    打破
    违约:
    blockSeed=emptyMarkdownText
    打破
    }
    const newBlockArray=blocks.concat({type:type,block:blockSeed})
    setblock([…newBlockArray]);
    };
    const removeBlock=(索引:number)=>{
    console.log(blocks)//记录一个空数组
    常数newBlockArray=块拼接(索引1);
    log(newBlockArray)//这记录了正确的数组
    setBlocks([…newBlockArray])
    }
    const updateBlock=(索引:编号,类型:字符串,块:故事块| MarkdownBlock)=>{
    let newBlockArray:Block[]=块;
    newBlockArray[index]={type:type,block:block};
    newBlockArray.forEach((block\u itr:block,i:number)=>{
    如果(i==索引){
    block\u itr.block=块
    block_itr.block.visibility=true
    }否则{
    block\u itr.block.visibility=false
    }
    })
    setblock([…newBlockArray]);
    };
    

    这里有一个指向的链接,但从我们已确定问题的注释来看,您正在将新块设置为
    splice()
    方法的结果,尽管该方法在适当位置变异数组并返回删除的元素。 相反,您应该克隆阵列,然后拼接它

    const removeBlock = (index: number) => {
      const newBlockArray = [...blocks];
      newBlockArray.splice(index, 1);
      setBlocks(newBlockArray)
    }
    

    请注意,上面执行的是数组的浅层复制,但在这种情况下这应该不是问题。

    FYI调用
    setBlocks
    不会立即更新状态。在组件重新加载之前,它不会更新。请尝试使用
    useCallback
    钩子定义
    removeBlock
    function@ToddSkelton我在检查使用
    useffect
    在每个渲染上禁用
    ,但它没有更新。因此我认为这意味着它甚至没有更新状态?我仍然不清楚为什么
    首先在函数中登录到
    未定义的
    ,即使我可以在视图中看到它,我可以打赌美元到你正在使用
    索引的甜甜圈
    >当呈现块时,作为
    。对于可变列表,您不能这样做,每个块都需要自己的唯一标识符作为
    属性。您也直接使用拼接来改变状态,这是错误的。您应该先从数组中复制,而不是直接处理
    const removeBlock = (index: number) => {
      const newBlockArray = [...blocks];
      newBlockArray.splice(index, 1);
      setBlocks(newBlockArray)
    }