javascript - api 块被调用 2 次,导致渲染组件两次,尽管条件得到了正确检查
问题描述
我在 setInterval 中使用 3 个动态变量,处于状态
this.state={
checked: true,
currentHash:"some current hash",
updating: true
}
在componentDidMount里面,我做了这样的事情
componentDidMount = () => {
let timer
timer = setInterval( (checked, currentHash, updating) => {
try {
this.setState({analysis:true});
if(checked){
var generatedHash = "current generated hash";
if (currentHash !== generatedHash) {
currentHash = generatedHash;
if(updating){
this.setState({updating:false})
const updateResponse = this.props.sendFile(DOCUMENT_ANALYSIS, ""); // my api call
}
else{
this.setState({analysis:false})
}
}
else{
this.setState({analysis:false})
}
clearInterval(timer);
this.componentDidMount();
}
else{
clearInterval(timer);
this.setState({analysis:false});
this.componentDidMount();
}
}
catch (error) {
console.log("Event error", error);
}
}, 10000, this.state.checked, this.state.currentHash, this.state.updating)
}
间隔设置为 10 秒。但在获得正确的状态数据之前,它调用了两次相同的函数。
解决方案
来自ReactJS的文档:
您可以立即在 componentDidMount() 中调用 setState()。它会触发额外的渲染,但会在浏览器更新屏幕之前发生。这保证了即使在这种情况下 render() 将被调用两次,用户也不会看到中间状态。请谨慎使用此模式,因为它通常会导致性能问题。在大多数情况下,您应该能够在 constructor() 中分配初始状态。但是,对于模态和工具提示等情况,当您需要在渲染取决于其大小或位置的内容之前测量 DOM 节点时,它可能是必要的。
看来 setInterval 可能会立即调用 setState 。
推荐阅读
- spring - 使用 Spring 5.0 WebClient 进行异步调用抛出连接被拒绝,很少成功调用
- node.js - 如何使用 peerDependencies 测试 npm 模块?
- python - 读取 os.popen() 输出不返回任何内容
- vue.js - 如何在 devtools 的 Vue 选项卡中显示数据?
- excel - 将文件名的一部分指定为变量
- css - 带渐变边框的透明圆形按钮
- sql - 需要 SQL 事务协助以在数据库中压缩数据
- python - 通过 pandas 从 JSON 加载文本值
- javascript - 在这种情况下,订阅一个简单的请求是 Angular 2 的正确方法吗?
- node.js - 如何使用 AWS.DynamoDB.DocumentClient 在 ExpressionAttributeValues 中表示数字类型