【问题标题】:Can't remove specific elements from array by index number from dynamic div element in react?无法通过反应中动态div元素的索引号从数组中删除特定元素?
【发布时间】:2021-09-15 01:36:07
【问题描述】:

我无法从任何动态 div 中按索引号删除数组的特定元素

const { useState } = React;

function Check(){
  var [Children, setChildren] = useState([])
    
  function RemArr(docs){
    const temp = [...Children]
    temp.splice(docs["i"], 1);
    setChildren(temp)
  } 
    
  function Product(docs) {
    var document = (<React.Fragment>
      <button onClick={()=>RemArr(docs)}>
        List {docs["i"]}
      </button>
      <p></p>
      <input/>
      <p></p>
    </React.Fragment>);
    setChildren([...Children, document])
  }

  return (<React.Fragment>
    <div>Check</div>
    {Children}
    <button
     onClick={()=>{Product({fix:false, i:Children.length})}}
    >Add List </button>
  </React.Fragment>)
}

ReactDOM.render(<Check />, document.body);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.0/umd/react-dom.production.min.js"></script>

当我想删除任何特定的 div 时,不仅要从数组中删除这个 div,还要从数组中删除下一个 div。

例如。

array = [0,1,2,3,4,5,6,7,8,9]

但是,如果我只想从数组中删除 6,它会删除从 69 的所有值,所以我只剩下:

array = [0,1,2,3,4,5]

我认为问题出在这个函数上:

function RemArr(docs){
  const temp = [...Children]
  temp.splice(docs["i"], 1);
  setChildren(temp)
}

【问题讨论】:

    标签: javascript arrays reactjs use-state


    【解决方案1】:

    您的RemArr 函数在Children 上有一个闭包,这意味着单击删除按钮将调用remArr 的潜在旧声明,其中remArr 内部的Children 数组将引用回最初添加 click 事件处理程序时的 Children 数组状态,而不是 Children 的当前状态。

    要克服这个问题,您可以将Product 组件化而不是使其成为一个函数,并根据Choice 中的某些状态驱动Children,您可以使用它来生成您的产品元素:

    const {useState} = React;
    
    function Product({docs, onClick}){
      return <React.Fragment>
        <button onClick={onClick}>
          List {docs.i}
        </button>
        <p></p>
        <input/>
        <p></p>
      </React.Fragment>;
    }
    
    function Check() {
      const [products, setProducts] = useState([]);
      function remArr(index){
        const temp = [...products];
        temp.splice(index, 1);
        setProducts(temp);
      }
      
      function addProduct() {
        const prevNum = products[products.length-1];
        setProducts([...products, {
          fix: false, 
          i: prevNum === undefined ? 0 : prevNum.i + 1
        }]);
      }
    
      return (<React.Fragment>
        <div>Check</div>
        {products.map(
          (doc, i) => <Product key={doc.i} docs={doc} onClick={() => remArr(i)}/>
        )}
        <button
         onClick={addProduct}
        >Add List</button>
      </React.Fragment>);
    }
    
    ReactDOM.render(<Check />, document.body);
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.0/umd/react.production.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.0/umd/react-dom.production.min.js"></script>

    上面创建新&lt;Product /&gt;组件的.map()方法“更新”/重新设置所有产品组件的onClick函数指向“最新”声明的remArr函数,它可以访问正确/最新的products 数组。这与您的示例不同,其中 Children 数组中的旧 JSX 对象仍然具有引用 remArr 函数的旧声明的 onClick 属性(可以访问旧的 Children 数组状态)

    【讨论】:

    • 我还是不明白。在 OPs 代码中,remArr 可以访问旧的 Children。但是这里不应该也是这样吗,remArr 应该可以访问旧的 Products 数组?
    • @TusharShahi 创建新的&lt;Product /&gt; 组件的.map()“更新”所有组件的onClick 函数以指向“最新”声明的remArr 函数,该函数可以访问正确/最新的products 数组。而在 OPs 代码中,Children 数组中的旧 JSX 对象仍然具有 onClick 属性,这些属性引用 remArr 函数的旧声明(可以访问旧的 Children 数组状态)
    • 嘿尼克帕森斯您的代码正在运行但不完全,因为如果我删除列表 4 或任何然后它删除 4 数字但我的输入不是从 4 数字字段中删除当单击删除它总是删除最后输入。 & 我还需要在主函数(Check)中初始化 Product 函数,因为我需要使用在 Check 函数中定义的 useState。那么如何在 Check 函数中使用 Product 函数呢?请。 & 我正在使用 Next js
    • @MunnyReol 嗨,我已经更新了 key 属性,以便解决输入问题。就在 Check 中初始化 Product 而言,永远不需要这样做。您可以在 Check 中维护您的状态,然后使用 props 将方法(例如 setProducs)传递到 Product 组件中,这将允许您在 Product 内部更新 Check 组件的状态
    • @MunnyReol 您可以更改i,因此它基于上一个列表项的编号加 1。我已经更新了 sn-p。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-03
    • 1970-01-01
    • 2014-11-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多