无法理解 JSX 点差运算符

IT技术 reactjs ecmascript-6 react-jsx
2021-04-06 05:16:56

鉴于来自 React 文档的此示例代码:

var props = {};
props.foo = x;
props.bar = y;
var component = <Component {...props} />;

我做了一些调查...props实际评估的内容,这是:

React.__spread({}, props)

反过来评估为{foo: x, bar: y}.

但我想知道的是,为什么我不能这样做:

var component = <Component props />;

我不明白传播运算符的意义是什么。

2个回答

这有助于使您的代码更加简洁 - 因为props是一个对象,所以扩展运算符获取您传入的对象属性并将它们应用于组件。因此,组件将具有特性的foo与值xbar具有的valuey

这将与以下内容相同:

var component = <Component foo={props.foo} bar={props.bar} />;

只是更短

reactpatterns.com上发布了关于对象-rest -spread 语法如何与 react协同工作的最佳概述之一

JSX 传播属性

Spread Attributes 是一个 JSX 特性。它是将对象的所有属性作为 JSX 属性传递的语法糖。

这两个例子是等价的。

// props written as attributes
<main className="main" role="main">{children}</main>

// props "spread" from object
<main {...{className: "main", role: "main", children}} />

使用它转发props到底层组件。

const FancyDiv = props =>
  <div className="fancy" {...props} />

现在,我可以期望FancyDiv添加它关注的属性以及它不关注的属性。

<FancyDiv data-id="my-fancy-div">So Fancy</FancyDiv>

// output: <div className="fancy" data-id="my-fancy-div">So Fancy</div>

请记住,顺序很重要。如果props.className被定义,它会破坏classNameFancyDiv

<FancyDiv className="my-fancy-div" />

// output: <div className="my-fancy-div"></div>

我们可以FancyDiv通过将 s className 放在 spread props 之后使它始终“获胜” ({...props})

// my `className` clobbers your `className`
const FancyDiv = props =>
  <div {...props} className="fancy" />

你应该优雅地处理这些类型的props。在这种情况下,我会将作者的props.classNameclassName需要的样式合并到我的组件中。

const FancyDiv = ({ className, ...props }) =>
  <div
    className={["fancy", className].join(' ')}
    {...props}
  />

-转引自reactpatterns.com通过@chantastic


Steven Luscher在 babeljs 博客文章React on ES6+ 上发表了另一个很好的概述

解构和传播属性

通常在组合组件时,我们可能希望将父组件的大部分 props 传递给子组件,但不是全部。将 ES6+ 解构与 JSX 扩展属性相结合,无需仪式就可以实现:

class AutoloadingPostsGrid extends React.Component {
  render() {
    const {
      className,
      ...others  // contains all properties of this.props except for className
    } = this.props;
    return (
      <div className={className}>
        <PostsGrid {...others} />
        <button onClick={this.handleLoadMoreClick}>Load more</button>
      </div>
    );
  }
}

-- 引自Steven Luscher 的“BabelJS.org 博客 - 在 ES6+ 上react”