- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试模拟在网络应用程序上运行的脚本。这个想法是脚本在后台运行并启动 http 请求,然后这些请求应显示为 <p>
。在一个分区中。但我不想让它走得太快。首先,状态更新太快不能正确更新,其次用户很难看到。
我试过使用 setTimeout,但这不起作用,因为它似乎设置了超时,然后继续 setState 而不等待。
AddParagraph = () => {
for(var i = 0; i < 20; i++){
setTimeout(function(){
this.setState({
urls: [...this.state.urls, www.url.com/i]
})},2000)
}
}
我读到在 for 循环中设置状态不是一个好主意,因为它没有时间快速渲染/更新。但是我看不出这样做的好主意,我不应该为此使用状态吗?
最佳答案
您似乎想要添加请求的 URL 并将其记录在网页上。
因此,您似乎对使用 for
更新状态“强制”感到困惑循环。
React 在本质上更像是一种声明,您的组件通常会对“状态”变化使用react。
所以不用 setTimeout
,这需要使用 for
循环,让我们以设定的时间间隔对状态变化做出“ react ”。
如我所见this.state
,我假设您使用的是 CC。
class ClassRequestViewer extends Component {
state = {
urls: [],
postId: 1
};
// To be used to clear the interval
// 👇 to prevent memory leaks
intervalId = undefined;
// Add a paragraph while setting the new post ID
// 👇 together in one shot.
addParagraph = () => {
const newUrl = `${urlRoot}/${this.state.postId}`;
this.setState(prevState => ({
urls: prevState.urls.concat(newUrl),
postId: prevState.postId + 1
}));
};
// 👇 You would want to initialize the interval only ONCE
// as the changing the state in `addParagraph` will
// cause `ClassRequestViewer` to re-render (in `render()` below).
componentDidMount() {
this.intervalId = setInterval(this.addParagraph, timeout);
}
// ⚠👇 is important!
// We need to make sure to clean up to prevent memory leak.
// OR else, the interval will run even if the component is unmounted
// and unavailable.
componentWillUnmount() {
this.intervalId && clearInterval(this.intervalId);
}
// 👇 Whenever "addParagraph" updates the state,
// This gets called, so will show the requests sent automatically.
render() {
const { urls } = this.state;
return (
<ul style={{ listStyle: "none" }}>
{urls.map(url => (
<li key={url}>Request sent to {url}</li>
))}
</ul>
);
}
}
现在您可以看到以给定时间间隔发送以呈现的请求列表。
我还在下面的 FC 中使用 Hook (useState
、useEffect
)实现了相同的 CC 版本。
代码看起来更小为 useEffect
有效地将关注点(setInterval
和 clearInterval
)“共同定位”在一个地方。
function RequestViewer() {
const [urls, setUrls] = useState([]);
const [postId, setPostId] = useState(1);
useEffect(() => {
function addParagraph() {
const newUrl = `${urlRoot}/${postId}`;
setUrls(_ => _.concat(newUrl));
setPostId(postId + 1);
}
const intervalId = setInterval(addParagraph, timeout);
return () => clearInterval(intervalId);
}, [postId]);
return (
<ul style={{ listStyle: "none" }}>
{urls.map(url => (
<li key={url}>Request sent to {url}</li>
))}
</ul>
);
}
没有for
在那里循环,因为useEffect
每当 postId
时更新改变了,这是每个 timeout
秒 setInterval
.
I want it to be started on an onClick event and stopped after X amount of rows. This seems to run endlessly?
正如您在 comment 中提到的那样, 它连续运行。
为了能够“开始/结束”该过程,您需要将“查看器”保留为查看器并处理父级上的显示。
因此,当您“启动”该过程时,查看器 ClassRequestViewer
将启动请求并向您显示结果,然后单击“停止”将卸载组件(这就是我使用 componentWillUnmount
到 clearInterval
的原因)。
我已经更新了 App
有 start/stop
按钮。
function App() {
const [isStarted, setIsStarted] = useState(false);
return (
<div className="App">
<h1>Request Viewer</h1>
{!isStarted && (
<button onClick={() => setIsStarted(true)}>Start the request</button>
)}
{isStarted && (
<>
<button onClick={() => setIsStarted(false)}>Stop Requests</button>
<ClassRequestViewer />
</>
)}
</div>
);
}
当您点击 Start the request
时按钮,它设置isStarted
至 true
,因此 ClassRequestViewer
已加载,您可以看到请求。
下面的代码已加载
{isStarted && (
<>
<button onClick={() => setIsStarted(false)}>Stop Requests</button>
<ClassRequestViewer />
</>
)}
当您点击 Stop Request
时按钮,设置isStarted
至 false
,因此,ClassRequestViewer
卸载,(依次调用 componentWillUnmount -> clearInterval
进行清理)。
然后你会看到 Start the request
再次按钮。
{!isStarted && (
<button onClick={() => setIsStarted(true)}>Start the request</button>
)}
下面是更新后的 App
的工作演示.
关于javascript - 在几秒钟内逐渐更新状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57364530/
我想要一个可以逐渐将页面底部的不透明度从 0 更改为 1 的函数。 我在元素的顶部使用了类似的功能,但我使用的不是淡入,而是淡出。创建它相当容易,但在页面底部使用设置的阈值淡入是一场噩梦。 经过研究,
li 状态是关闭和打开。 闭合:颜色为黑色(没有光照,相互折叠)。 打开:颜色为红色(有光,全视野)。 我希望颜色从两个元素之间的点开始淡化,以表明阴影从轴心开始,直到它们关闭。 $('button'
我的问题很简单: 1)我有一个扩展 JFrame 的主类。 2)该类内部有一个 JPanel,其顶部有一个 BufferedImage。 3)最后还有一个 JButton,我称之为“Fire”..这就
我有这个立方体,我想在延迟 3000 后将其转换为不同的 X 和 Y 点。我无法理解如何在 jQuery 的帮助下做到这一点。这是一个JS Fiddle .下面是代码。 JS // code for
我们如何向背景图像添加黑色阴影,阴影从不透明度 1 开始逐渐降低到不透明度 0,在图像的所有 4 个边上? (至少 50 像素值的“降低阴影不透明度”。box-shadow 仅提供少量不透明度逐渐下降
我是一名优秀的程序员,十分优秀!