首页 > 解决方案 > React returns older state value onClick

问题描述

I am adding a component onclick and keeping track of the components using useState Array. However when I go to remove one of the added components, it doesn't recognize the full component Array size, only the state that was there when that component was initially added.

Is there a way to have the current state recognized within that delete function?

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>
    </>
  );
}

标签: javascriptreactjsreact-hooks

解决方案


更新 -解释您为什么面临问题中描述的问题

当您在状态上添加新跨度时,它就像捕获周围当前值的图像,包括spans. 这就是为什么登录spans点击会返回一个不同的值。这是您将您的状态spans添加<Span />到您的状态时所具有的价值。

这是闭包的好处之一。你添加的每一个<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>
    </>
  );
}

我希望这可以帮助您找到自己的方式。


推荐阅读