Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jsp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 为什么在通过setTimeout进行状态更新之前,三元运算符的不可到达部分会被评估?_Javascript_Reactjs_Settimeout_Jsx_Ternary Operator - Fatal编程技术网

Javascript 为什么在通过setTimeout进行状态更新之前,三元运算符的不可到达部分会被评估?

Javascript 为什么在通过setTimeout进行状态更新之前,三元运算符的不可到达部分会被评估?,javascript,reactjs,settimeout,jsx,ternary-operator,Javascript,Reactjs,Settimeout,Jsx,Ternary Operator,我有以下代码,这是一个react组件,呈现了一个巨大的组件。只要这个巨大的组件还没有完成渲染,就会显示一个加载指示器 import * as React from "react"; import ReactDOM from "react-dom"; import {HUGEComponent} from "./huge.tsx"; class App extends React.Component<{}, {loading: boolean}> { constructor(p

我有以下代码,这是一个react组件,呈现了一个巨大的组件。只要这个巨大的组件还没有完成渲染,就会显示一个加载指示器

import * as React from "react";
import ReactDOM from "react-dom";

import {HUGEComponent} from "./huge.tsx";

class App extends React.Component<{}, {loading: boolean}> {
  constructor(props: {}) {
    super(props);
    this.state = {loading: true};
  }

  componentDidMount() {
    setTimeout(() => this.setState({loading: false}), 0);
  }

  render() {
    return this.state.loading ? <p>Loading...</p> : <HUGEComponent />;
  }
}

ReactDOM.render(<App />, document.getElementById("root"));
import*as React from“React”;
从“react dom”导入react dom;
从“/maging.tsx”导入{HUGEComponent};
类应用程序扩展了React.Component{
构造函数(props:{}){
超级(道具);
this.state={loading:true};
}
componentDidMount(){
setTimeout(()=>this.setState({loading:false}),0);
}
render(){
返回this.state.loading?加载…

:; } } render(,document.getElementById(“根”));
componentDidMount
中的
setTimeout
函数确保只有在加载了
HUGEComponent
之后才会进行状态更新(我使用了10000段lorem ipsum作为
HUGEComponent
)。如果没有
setTimeout
,状态将立即更新,并且加载指示器不会显示


所以我的问题是,为什么要用
setTimeout
?我知道,它会将状态更新推送到消息队列,因此在完成所有其他工作后,将执行消息队列。但由于使用了三元运算符(延迟求值),因此实际呈现的
HUGEComponent
应该等到状态更新之后,以便在呈现之前进行状态更新,但这似乎不是真的。只要未计算
,状态实际上不会更新。那么,为什么在状态更新之前,尽管三元运算符中的计算是惰性的,但仍要对其进行计算呢?

可能是因为这个原因

您可以在componentDidMount()中立即调用setState()。它将触发额外的渲染,但会在浏览器更新屏幕之前发生。这保证了即使在这种情况下render()将被调用两次,用户也不会看到中间状态。请谨慎使用此模式,因为它通常会导致性能问题。在大多数情况下,您应该能够在构造函数()中指定初始状态。但是,对于modals和工具提示这样的情况,当您需要在呈现取决于其大小或位置的对象之前测量DOM节点时,它可能是必需的。


一个类似的问题可以解释为什么:

我认为你对事件的解释是错误的。实际上,状态更新并不是等待HugeComponent求值,而是立即发生,这会触发重新渲染器并导致HugeComponent求值。在HugeComponent求值时,您不会在DOM中看到任何更改,因此这就是在HugeComponent求值时加载文本可见的原因


对于不使用setTimeout的情况,@tan dat的回答是有意义的。当未使用setTimeout时,用户将看不到中间状态(即加载文本)。

如果使用If/else语句而不是三元运算符,它是否也能工作?三元运算符中的“延迟加载”是什么意思
HUGEComponent
将在
loading
false
之前不会被呈现@Thole抱歉,我的意思是懒惰的评估您是如何得出这个结论的:
只要没有呈现,状态就不会被更新。
没有任何绑定状态HugeComponent@Kornflexx是的,似乎没有区别