React返回旧状态值onClick

时间:2020-01-07 20:15:42

标签: javascript reactjs react-hooks

我正在添加组件onclick并使用useState Array跟踪组件。但是,当我删除其中一个添加的组件时,它无法识别完整的组件数组大小,只能识别最初添加该组件时的状态。

是否可以通过该删除功能识别当前状态?

https://codesandbox.io/s/twilight-water-jxnup

import React, { useState } from "react";

export default function App() {
  const Span = props => {
    return (
      <div>
        <span>{props.index}</span>
        <button onClick={() => deleteSpan(props.index)}>DELETE</button>
        Length: {spans.length}
      </div>
    );
  };
  //set initial span w/ useState
  const [spans, setSpans] = useState([<Span key={0} index={Math.random()} />]);
  //add new span
  const addSpan = () => {
    let key = Math.random();
    setSpans([...spans, <Span key={key} index={key} />]);
  };
  //delete span
  const deleteSpan = index => {
    console.log(spans);
    console.log(spans.length);
  };
  //clear all spans
  const clearInputs = () => {
    setSpans([]);
  };
  return (
    <>
      {spans}
      <button onClick={() => addSpan()}>add</button>
      <button onClick={() => clearInputs()}>clear</button>
    </>
  );
}

1 个答案:

答案 0 :(得分:0)

更新-解释为什么您遇到问题中所描述的问题

在状态上添加新跨度时,就好像它捕获了周围当前值(包括值spans)的图像。这就是为什么在点击时记录spans会返回不同的值的原因。这是将spans添加到状态时的<Span />值。

这是Closures的好处之一。您添加的每个<Span />都会创建一个不同的闭包,并引用不同版本的spans变量。


将组件推入状态是否有原因?我建议您保持状态整洁。这样,它也是可重用的。

例如,您可以使用useState创建一个空数组,您将在其中推送与spans相关的数据。出于示例的目的,我将仅推送一个时间戳,但是对于您来说可能是另外一回事了。

export default function App() {
  const Span = props => {
    return (
      <div>
        <span>{props.index}</span>
        <button onClick={() => setSpans(spans.filter(span => span !== props.span))}>DELETE</button>
        Length: {spans.length}
      </div>
    );
  };

  const [spans, setSpans] = React.useState([]);

  return (
    <>
      {spans.length
        ? spans.map((span, index) => (
            <Span key={span} index={index} span={span} />
          ))
        : null}
      <button onClick={() => setSpans([
        ...spans,
        new Date().getTime(),
      ])}>add</button>
      <button onClick={() => setSpans([])}>clear</button>
    </>
  );
}

我希望这可以帮助您找到路。