JSX:什么时候评估JavaScript表达式?

时间:2019-01-29 04:43:47

标签: javascript reactjs jsx gatsby

阅读完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表达式?

1 个答案:

答案 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"
);

Play with babel here

我们放在方括号之间的任何内容都将作为div元素的子元素传递给React.createElement;因此只能在此处放置有效的React元素:

  • 为空(不显示任何内容)
  • 字符串(将成为DOM文本节点)
  • 另一个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>