Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/456.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 向数组中添加元素并从前面移除元素,每次一个,每2秒一个,直到数组为空?_Javascript_Arrays_Reactjs_React Native - Fatal编程技术网

Javascript 向数组中添加元素并从前面移除元素,每次一个,每2秒一个,直到数组为空?

Javascript 向数组中添加元素并从前面移除元素,每次一个,每2秒一个,直到数组为空?,javascript,arrays,reactjs,react-native,Javascript,Arrays,Reactjs,React Native,所以,我使用react,有一个按钮,当我按下按钮时,它会使用useState将元素添加到数组中。现在,一旦我添加了第一个元素,我想每隔1秒删除第一个元素,直到数组为空并且我不再按下按钮 我可以继续按并添加项目,但在2秒钟后,可能使用计时器,它也应该继续从阵列前端移除 const [id, addId] = useState([]) <button onClick={()=> addId([...id,newId])> Add Id </button> cons

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

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

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

<button onClick={()=> addId([...id,newId])> Add Id </button> 
const[id,addId]=useState([]
addId([…id,newId])>addId
因此,我得到了一个视图,它通过ID循环并在屏幕上绘制它们。现在,当它被绘制时,它应该会逐渐消失,并且在我第一次按下按钮并每隔2秒移除它们之后,它也会从阵列中移除

我无法正确使用setInterval、setTimeout和useEffect。它以无限循环结束

比方说,我按下3次,数组将是[1,2,3],1秒后,它应该是[2,3],然后1秒后,它应该是[3],最后以一个空数组[]停止。一旦我按下按钮,移除过程应该不会停止,直到阵列为空,即使我停止按下按钮


希望现在我想要的已经清楚了

您可以选择
setInterval
并检查数组是否有值

函数添加(){
array.push(Math.floor(Math.random()*10));
document.getElementById('values').innerHTML=array.join('');
}
常量数组=[];
设置间隔(()=>{
如果(!array.length)返回;
数组。shift();
document.getElementById('values').innerHTML=array.join('');
}, 1000);
点击

在组件外部初始化interval变量,以便在组件中发生任何重新渲染时它不会更改。在component did mount(使用效果)中,设置interv,该interv将每秒触发一次,并从数组中移除元素(shift或pop)并更新状态。在卸载时,清除间隔。

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

(编辑:这是基于codesandbox链接BTW)

从“React”导入React;
导入“/styles.css”;
导出默认函数App(){
常数延迟=2000;
const[ids,setIds]=React.useState([]);
const timeout=React.useRef(null);
const id_length=React.useRef(null);
函数集\u删除\u标识\u超时(){
if(超时。当前)
clearTimeout(timeout.current);
timeout.current=setTimeout(()=>{
如果(ids_length.current==0)返回;
ids_length.current=ids_length.current-1;
setid(([first,…others])=>[…others]);
设置删除ID超时();
},延误);
}
函数add(){
ids_length.current=ids.length+1;
setid([…id,(id[id.length-1]| | 0)+1]);
设置删除ID超时();
}
React.useffect(()=>{
return()=>{if(timeout.current)clearTimeout(timeout.current);};
}, []);
日志(“ids添加”,ids);
返回(
添加Id
{ids.map((i)=>(

{i}

))} ); }
编辑。。。所以有可能是我不/不明白在点击按钮后,删除何时恢复。。。因此,如果按钮点击不应影响移除延迟,那么类似的操作可能会起作用:

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>
  );
}
从“React”导入React;
导入“/styles.css”;
导出默认函数App(){
常数延迟=2000;
const[ids,setIds]=React.useState([]);
const interval=React.useRef(null);
const id_length=React.useRef(null);
函数集\u删除\u标识\u间隔(){
如果(!interval.current){
interval.current=setInterval(()=>{
log(“ids_length.current”,ids_length.current);
如果(ids_length.current==0){
clearInterval(interval.current);
interval.current=null;
返回;
}
ids_length.current=ids_length.current-1;
setid(([first,…others])=>[…others]);
设置删除标识间隔();
},延误);
}
}
函数add(){
ids_length.current=ids.length+1;
setid([…id,(id[id.length-1]| | 0)+1]);
设置删除标识间隔();
}
React.useffect(()=>{
return()=>{
if(interval.current)clearInterval(interval.current);
};
}, []);
日志(“ids添加”,ids);
返回(
添加Id
{ids.map((i)=>(

{i}

))} ); }
什么不起作用?我已经更新了@ninascholz这个问题,但是,我的组件没有重新渲染,所以我无法看到元素消失。我需要这个来处理。效果应该与我在标签中显示的数字相似。对不起,我不知道如何反应。谢谢,非常感谢!这是一个开始@Nina Scholz
.shift
在适当的位置变异数组。是的,我犯了一个错误。我修复了它。另外,我注意到
interval
是在
useffect
之外定义的,这意味着如果组件的另一个实例被创建,它将被破坏。我刚刚意识到您正在使用
数组,它在组件的装载上被捕获,并且永远不会得到新的值,所以这也不起作用。您需要使用更新程序回调参数:
setArray(([first,…newArray])=>newArray)
嘿,Ben Stephen,这可以满足我的需要,谢谢,但是,不使用ref可以吗?@Rishav我想您可以尝试将
let interval
let id_length
声明在组件范围之外(就像stellyrepsolka的回答,但是(我认为)让我们来代替const)但是(根据Emile Bergeron的评论)这就限制了您只能使用组件的一个实例。您可能可以对interval\u id使用state,但我想知道,当传递给setInterval的函数运行时,该函数中的interval\u id是否已过时,因此clearInterval(interval\u id)将无法工作
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>
  );
}