【问题标题】:Trouble understanding JSX spread operator [duplicate]无法理解 JSX 传播运算符 [重复]
【发布时间】:2015-11-28 14:19:14
【问题描述】:

鉴于这个来自 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 />;

我不明白展开运算符的意义是什么。

【问题讨论】:

标签: reactjs ecmascript-6 react-jsx


【解决方案1】:

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

它与以下内容相同:

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

只是更短

【讨论】:

    【解决方案2】:

    关于 object-rest-spread 语法如何与 react 一起工作的最佳概述之一发布在 reactpatterns.com

    JSX 传播属性

    传播属性是一个 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,它将破坏FancyDiv定义的className

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

    我们可以通过将FancyDivs className 放在传播道具({...props}) 之后,使其始终“获胜”。

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

    您应该优雅地处理这些类型的道具。在这种情况下,我会将作者的 props.className 与设置组件样式所需的 className 合并。

    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 blog - React on ES6+"

    【讨论】:

      猜你喜欢
      • 2018-05-08
      • 2023-03-29
      • 2013-09-06
      • 1970-01-01
      • 2016-06-26
      • 1970-01-01
      • 2023-03-19
      • 2016-09-05
      • 1970-01-01
      相关资源
      最近更新 更多