首页 > 解决方案 > 将元素添加到数组并从前面删除元素,一次一个,每 2 秒一次,直到数组为空?

问题描述

所以,我正在使用 react 并有一个按钮,当我按下按钮时,它使用 useState 将元素添加到数组中。现在,一旦我添加了第一个元素,我想在每 1 秒后删除第一个元素,直到数组为空并且我不再按下按钮。

我可以继续按下并添加项目,但在 2 秒过去后,可能使用计时器,它也应该继续从阵列的前面移除。

const [id, addId] = useState([])

<button onClick={()=> addId([...id,newId])> Add Id </button> 

所以,我有一个循环遍历 ID 并将它们绘制在屏幕上的视图。现在,当它被绘制时,它应该会消失,并且在我第一次按下按钮并每 2 秒将其移除后,它也会从阵列中移除。

我无法正确使用 setInterval、setTimeout 和 useEffect。它最终陷入无限循环......

假设我按了 3 次,数组将是 [1,2,3],1 秒后,它应该是 [2,3],然后 1 秒后,它应该是 [3],最后以一个空数组停止[]。一旦我按下按钮,即使我停止按下按钮,删除过程也不应该停止,直到数组为空。

希望现在清楚我想要什么

标签: javascriptarraysreactjsreact-native

解决方案


这是我的尝试,虽然它可能比我想要的更混乱:

(编辑:这是基于代码和框链接顺便说一句。)

import React from "react";
import "./styles.css";

export default function App() {
  const delay = 2000;
  const [ids, setIds] = React.useState([]);

  const timeout = React.useRef(null);
  const ids_length = React.useRef(null);

  function set_remove_ids_timeout() {
    if(timeout.current)
      clearTimeout(timeout.current);
    
    timeout.current = setTimeout(() => {
      if (ids_length.current === 0) return;
      ids_length.current = ids_length.current - 1;
      setIds(([first, ...others]) => [...others]);
      set_remove_ids_timeout();
    }, delay);
  }

  function add() {
    ids_length.current = ids.length + 1;
    setIds([...ids, (ids[ids.length - 1] || 0) + 1]);
    set_remove_ids_timeout();
  }

  React.useEffect(() => {
    return () => { if(timeout.current) clearTimeout(timeout.current); };
  }, []);

  console.log("ids adding", ids);
  return (
    <div className="App">
      <button onClick={add}> Add Id </button>
      {ids.map((i) => (
        <p key={i}>{i}</p>
      ))}
    </div>
  );
}

编辑......所以我可能没有/不明白在单击按钮后恢复何时恢复删除......所以如果按钮单击不应该影响删除延迟,也许这样的事情会起作用:

import React from "react";
import "./styles.css";

export default function App() {
  const delay = 2000;
  const [ids, setIds] = React.useState([]);

  const interval = React.useRef(null);
  const ids_length = React.useRef(null);

  function set_remove_ids_interval() {
    if (!interval.current) {
      interval.current = setInterval(() => {
        console.log("ids_length.current", ids_length.current);
        if (ids_length.current === 0) {
          clearInterval(interval.current);
          interval.current = null;
          return;
        }
        ids_length.current = ids_length.current - 1;
        setIds(([first, ...others]) => [...others]);
        set_remove_ids_interval();
      }, delay);
    }
  }

  function add() {
    ids_length.current = ids.length + 1;
    setIds([...ids, (ids[ids.length - 1] || 0) + 1]);
    set_remove_ids_interval();
  }

  React.useEffect(() => {
    return () => {
      if (interval.current) clearInterval(interval.current);
    };
  }, []);

  console.log("ids adding", ids);
  return (
    <div className="App">
      <button onClick={add}> Add Id </button>
      {ids.map((i) => (
        <p key={i}>{i}</p>
      ))}
    </div>
  );
}

推荐阅读