admin管理员组文章数量:1336645
I have tried solutions related with Javascript and React using state, but I can't do it with Hooks. I want to add 3 seconds delay for each element that I'm rendering on array.map
import React, { useState } from 'react';
const DelayMapHooks = () => {
const [array, setArray] = useState([1, 2, 3])
return (
<div>
{
array.map((elem, key) => {
// ADD DELAY HERE FOR EACH ELEMENT
return( <div>Number: {elem}</div> )
})
}
</div>
);
};
export default DelayMapHooks;
I have tried adding an await/async immediately after the map, using await delay(3000)
with the function
const delay = ms => {return(new Promise(res => setTimeout(res, ms)))}
But it doesn't work, showing the error: Objects are not valid as a React child (found: [object Promise]). Appreciated any help.
I have tried solutions related with Javascript and React using state, but I can't do it with Hooks. I want to add 3 seconds delay for each element that I'm rendering on array.map
import React, { useState } from 'react';
const DelayMapHooks = () => {
const [array, setArray] = useState([1, 2, 3])
return (
<div>
{
array.map((elem, key) => {
// ADD DELAY HERE FOR EACH ELEMENT
return( <div>Number: {elem}</div> )
})
}
</div>
);
};
export default DelayMapHooks;
I have tried adding an await/async immediately after the map, using await delay(3000)
with the function
const delay = ms => {return(new Promise(res => setTimeout(res, ms)))}
But it doesn't work, showing the error: Objects are not valid as a React child (found: [object Promise]). Appreciated any help.
Share Improve this question asked Aug 27, 2020 at 14:50 maxrojasmaxrojas 1811 gold badge3 silver badges8 bronze badges3 Answers
Reset to default 5You can't block the render method like that, render should run synchronously. This can be done with useEffect though, you need to modify the state of the array each period. React will then reconcile the DOM and render an extra element every second.
useEffect(() => {
const interval = setInterval(() => {
// You'd want an exit condition here
setArray(arr => [...arr, arr.length + 1]);
}, 1000);
return () => clearInterval(interval);
}, []);
Does this work for you? The delay needs to be handled through state. Either adding the items over time or a visibility property.
import React, { useEffect, useState } from "react";
const DelayMapHooks = () => {
const [array, setArray] = useState([]);
useEffect(() => {
for (let i = 1; i <= 3; i++) {
setTimeout(() => setArray((prevState) => [...prevState, i]), 3000 * i);
}
}, []);
return (
<div>
{array.map((elem, key) => {
return <div>Number: {elem}</div>;
})}
</div>
);
};
export default DelayMapHooks;
You could still use delay, but require some more works
- iterate
array
with delay using IIFE async function - after delay, set the element to be displayed and have a
useEffect
hook to listen to that update, and then append the to-be-displayed element to a new array using for rendering
const [array] = React.useState([1, 2, 3, 4, 5])
const [displayArray, setDisplayArray] = React.useState([])
const [displayEl, setDisplayEl] = React.useState()
const delay = (ms) =>
new Promise((res) => {
setTimeout(() => {
res()
}, ms)
})
React.useEffect(() => {
(async function () {
for (let el of array) {
await delay(1000)
setDisplayEl(el)
}
setDisplayEl(undefined)
})()
}, [array])
React.useEffect(() => {
displayEl && setDisplayArray((prev) => [...prev, displayEl])
}, [displayEl])
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
{displayArray.map((elem, key) => (
<div key={key}>Number: {elem}</div>
))}
</div>
)
Codesandbox for demo (refresh to see from the beginning)
本文标签: javascriptAdd delay into a map with React HooksStack Overflow
版权声明:本文标题:javascript - Add delay into a map with React Hooks - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742243774a2439001.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论