遍历数组并一次显示具有动态持续时间的单个项目,例如 react js 中的 setTimeout 或 SetInterval

loop through an array and show single item at a time with dynamic time duration like setTimeout or SetInterval in react js

我有一个 Media.json 文件,其中有 6 个媒体对象(名称、持续时间、文件类型)。我想遍历它们,并希望根据媒体对象持续时间 属性 一次显示一个具有动态持续时间的项目。我已经尝试使用 setTimeout 和 SetInterval 在它们内外循环但仍然无法做到这一点。我正在将 react js 与功能组件一起使用。帮助将不胜感激。我的示例代码。

const [mediaItem, setMediaItem] = useState({})
const items = [{ name: 'one' }, { name: 'two' }, { name: 'three' }];
const renderMedia = () => {
for (let i = 0; i < items.length; i++) {
  setTimeout(() => {
    setMediaItem(items[i]);
    console.log(mediaItem);
  }, 5000);
}
// return items[currentIndex].name;

};

谢谢

问题

  1. for循环是完全同步的代码。在循环中更新反应状态时,您必须使用功能状态更新,否则每个后续排队的更新都会覆盖之前的更新。
  2. for 循环在组件主体中,这意味着每次组件由于状态更新而重新呈现时,都会设置另一组入队状态更新。

解决方案

如果您想在同步循环中对所有更新进行排队,那么应该在挂载 useEffect 挂钩中完成一次并对超时应用增量,这样它们就不会同时过期.

useEffect(() => {
  items.forEach((item, i) => setTimeout(
    () => setMediaItem(item),
    (i + 1) * 5000, // 5000, 10000, 15000
  ));
}, []);

use/store 状态中的数组 index 并按间隔递增它可能更容易一些。

const items = [{ name: "one" }, { name: "two" }, { name: "three" }];

function AppExample() {
  const [mediaItem, setMediaItem] = React.useState(items[0]); // <-- seed initial state
  const [index, setIndex] = React.useState(0);

  React.useEffect(() => {
    const timerId = setInterval(
      () => setIndex((i) => (i + 1) % items.length), // <-- increment index
      2000
    );
    return () => clearInterval(timerId);
  }, []);

  React.useEffect(() => {
    setMediaItem(items[index]); // <-- update media state when index updates
  }, [index]);

  return (
    <div className="App">
      <div>Media: {mediaItem.name}</div>
    </div>
  );
}