阅读完GatsbyJS和React教程后,我得到的印象是,当JavaScript表达式位于JSX中的{}括号内时,总是对其进行评估。但是,现在我正在看GatsbyJS初始存储库中的JSX文件,看起来好像括号会引起不同的行为:
const {
data: {
posts: { edges: posts },
site: {
siteMetadata: { facebook }
}
}
} = props;
(Source)
根据教程,“ facebook”应被评估为JavaScript,并且应返回未定义的内容,但这不是正在发生的事情。不知何故,我们最终得到了一个JavaScript对象data.site.siteMetadata.facebook,其中包含一些数据。这里发生了什么?为什么“ facebook”没有被评估为JavaScript表达式?
答案 0 :(得分:1)
您复制的代码实际上与JSX无关(请参见下文)。是ES6 object destructuring syntax,就像@PrithvirajSahu在这个问题上发表了评论。
假设您有一个像这样的对象:
const obj = {
a: 100,
b: {
value: 200,
}
};
您可以像这样获得内部值:
const { a } = obj;
// same as const a = obj.a
const { b: c } = obj;
// same as const c = obj.b
const { b: { value } } = obj;
// same as const value = obj.b.value
const { b: { value: v } } = obj;
// same as const v = obj.b.value
const { a, { b: { value } } } = obj;
// same as
// const a = obj.a;
// const value = obj.b.value;
所以回到您的代码段,它等同于
const posts = props.data.posts.edges;
const facebook = props.data.site.siteMetadata.facebook;
正如您所发现的那样,解构语法在1或2个级别上非常简洁,但是在更多级别时很难阅读。就我个人而言,我仅以1级使用它。
编辑:在源代码中的功能中,只有以<...
开头的行才是JSX语法。
const CategoryPage = props => {
// code here is normal js
const { ... } = props;
// JSX start from inside this return function
return (
<React.Fragment>
{ /* code between bracket in this section will be evaluate as 'normal JS' */ }
</React.Fragment>
)
}
注意:JSX中括号之间的代码必须评估为一个函数。如果我们这样写:
<div className="container">
Hello
{"Happy"}
World
</div>
Babel会将其转换为以下常规JS:
React.createElement(
"div",
{ className: "container" },
"Hello",
"Happy",
"World"
);
我们放在方括号之间的任何内容都将作为div
元素的子元素传递给React.createElement
;因此只能在此处放置有效的React元素:
<div>
{ hasDate && <Date /> }
<div>
或
// somewhere in the code
const showDate = (hasDate) => {
if (!hasDate) return null;
return <Date />
}
// in the render function
return (
<div>
{ showDate(hasDate) }
<div>
)
我们还可以使用方括号将值传递给元素的道具:
<div
style={ { color: 'red' } }
onClick={ (event) => {...} }>
{ hasDate && <Date /> }
<div>