所以我的有状态状态组件中有类似的内容(我正在关注一些反应教程)
class FullPost extends Component {
state = {
loadedpost: null
}
componentDidUpdate () {
if (this.props.id) {
if (!this.state.loadedpost || this.state.loadedpost && this.state.loadedpost.id !== this.props.id) {
axios.get("https://jsonplaceholder.typicode.com/posts/" + this.props.id).then(response => {
this.setState({loadedpost: response.data})
})
}
}
}
在上面的代码中,请看此行
if (!this.state.loadedpost || this.state.loadedpost && this.state.loadedpost.id !== this.props.id)
我们是说如果this.state.loadedpost
为真甚至为假时执行的代码?因此我认为此检查是不必要的,因此将其删除。这使我的代码像这样
if ( this.state.loadedpost.id !== this.props.id) {
但这会引发错误,提示this.state.loadedpost.id
(实际上错误是无法读取null的属性“ id”)。之所以能得到它,是因为在this.state.loadedpost.id中还没有任何内容(在我们的第一个请求中)
[问题] 但是,为什么我们使用第一个提到的代码时不会出现相同的错误?即
if (!this.state.loadedpost || this.state.loadedpost && this.state.loadedpost.id !== this.props.id)
答案 0 :(得分:3)
为什么在使用第一个提到的代码时不会出现相同的错误?
由于||
短路。当发现this.state.loadedpost
是伪造的时,它立即将那个伪造的值作为结果,并且根本不评估右侧。因此this.state.loadedpost.id
不会被评估(因此不会导致错误)。
您的版本:
if ( this.state.loadedpost.id !== this.props.id) {
始终尝试从id
读取this.state.loadedpost
,如果this.state.loadedpost
是undefined
,null
等,则会失败。
该语句 可以缩短,this.state.loadedpost &&
部分没有理由:
if (!this.state.loadedpost || this.state.loadedpost.id !== this.props.id)
答案 1 :(得分:1)
因为if语句短路。
假设您要问A OR B是否为真。 如果A为true,则不需要评估B,因为我们有足够的信息来继续执行。
答案 2 :(得分:1)
由于Javascript的逻辑评估规则,因此存在一个快捷方式,如果||
的第一个条件为true,则以后的任何评估都不会进行评估,因此, ||
从未评估
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_Operators
当逻辑表达式从左到右求值时,将使用以下规则对它们进行测试以进行可能的“短路”评估:
false &&(任何东西)被短路评估为false。
true || (任何)短路评估为真。
答案 3 :(得分:0)
因为if
已优化。
您的this.state.loadedpost
是null
,因此它停止了进一步的评估:
if (!this.state.loadedpost || anythingElse) -> if (true || anythingElse)
答案 4 :(得分:0)
当true
的{{1}}与id
不同时,条件为this.state.loadedpost
。
第一个条件(this.props.id
)确保对最后一个表达式(!this.state.loadedpost
)的求值不会尝试访问不存在的对象的this.state.loadedpost.id !== this.props.id
属性({{ 1}}尚未设置。
当id
为this.state.loadedpost
(因为!this.state.loadedpost
为true
)时,整个表达式为this.state.loadedpost
(由于undefined
),并且其余部分不进行评估(JavaScript会缩短逻辑表达式)。
不需要第二个条件(true
)。仅当第一个条件为||
且第二个条件始终为this.state.loadedpost
且第一个条件为false
时,才对它进行评估。
可以简化表达式,而无需将其含义更改为:
true
答案 5 :(得分:0)
&&
的优先级高于||
(认为5 + 3 * 2 === 5 +(3 * 2))
因此
if (!this.state.loadedpost || this.state.loadedpost && this.state.loadedpost.id !== this.props.id)
等效于(看括号)
if (
!this.state.loadedpost ||
(this.state.loadedpost && this.state.loadedpost.id !== this.props.id)
)
因此,回答您的问题
我们是说如果
this.state.loadedpost
为真甚至为假时执行的代码?
是“不,我们不。”
但是,由于短路评估,您可以缩短条件:
if (
!this.state.loadedpost ||
this.state.loadedpost.id !== this.props.id // this evaluates only if !this.state.loadedpost is false
)