arrays - 循环遍历数组并一次显示单个项目,动态持续时间,如 react js 中的 setTimeout 或 SetInterval
问题描述
我有一个 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;
};
谢谢
解决方案
问题
- for 循环是完全同步的代码。在循环中更新反应状态时,您必须使用功能状态更新,否则每个后续排队更新都会覆盖先前的更新。
- for 循环位于组件主体中,这意味着每次组件由于状态更新而重新渲染时,都会设置另一组入队状态更新。
解决方案
如果您想在同步循环中将所有更新排队,那么应该在挂载useEffect
钩子中完成一次,并对超时应用增量,这样它们就不会同时过期。
useEffect(() => {
items.forEach((item, i) => setTimeout(
() => setMediaItem(item),
(i + 1) * 5000, // 5000, 10000, 15000
));
}, []);
在状态中使用/存储数组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>
);
}
推荐阅读
- reactjs - 使用 GitHub Action [CI/CD] 部署 AWS S3 时如何设置自定义环境变量以响应应用程序
- r - 使用 ets() 时,为什么 R 没有响应并崩溃?
- r - R 中的引导程序:t.star[r, ] <- res[[r]] 中的错误:要替换的项目数不是替换长度的倍数
- react-native - 如何计算反应原生平面列表项目中的视图
- c# - 如果值为 null,则 C# 跳过该值并转到下一个值 json 属性 Azure DevOps Rest API
- r - 将 ggplot-y 变量作为条件参数处理以动态适应绘图层(此处:通过使用 case_when 调整面板背景颜色)
- php - 如何使用 PHP 从 ajax 响应中删除 HTML 标签?
- c - 有人可以发现我的代码中的错误吗?我不知道我错过了什么以及我搞砸了什么
- regex - 什么是匹配文件夹、隐藏文件夹、普通文件的正确 awk 正则表达式,所以我可以使用转义码为它们着色,以及将语法放在哪里
- javascript - 如何在 chrome 扩展中添加和链接多个 html