【问题标题】:Is the ordering of props in JSX important?JSX 中 props 的顺序重要吗?
【发布时间】:2017-11-19 08:23:33
【问题描述】:

如果 o 对象包含以下键/值对:foo: 'bar' 我可以依赖这些结果吗?:

// foo will be 'bar'
<MyComponent
    foo='should not override'
    {...o}
  />

// foo will be 'overridden'
<MyComponent
    {...o}
    foo='overridden'
  />

换句话说,使用spread 运算符时属性的顺序是否重要?

【问题讨论】:

    标签: javascript reactjs ecmascript-6 react-jsx spread-syntax


    【解决方案1】:

    是的,是的。它完全按照您的示例所说的那样工作

    你的例子被翻译成:

    // foo will be 'bar'
    <MyComponent
        {/* ...other 'o' keys/values...*/}
        foo='should not override'
        {/* ...other 'o' keys/values...*/}
        foo='bar'
    />
    
    // foo will be 'overridden'
    <MyComponent
        foo='bar'
        {/* ...other 'o' keys/values...*/}
        foo='overridden'
        {/* ...other 'o' keys/values...*/}
    />
    

    因此,它总是覆盖最后一个

    【讨论】:

      【解决方案2】:

      是的,订购确实很重要。确切的原因是 Babel 如何转译 JSX。你可以在Babel REPL看到这个:

      <MyComponent foo="should not override" {...o}>
      
      </MyComponent>
      

      变成:

      React.createElement(MyComponent, _extends({ foo: "overridden" }, o));
      

      其中_extends 只是Object.assign,或者如果浏览器不支持它,_extends 在功能上是相同的。根据 MDN 文档:

      如果目标对象中的属性具有相同的键,它们将被源中的属性覆盖。以后源的属性将类似地覆盖早期的属性。

      (重点是我的)。因此,当使用Object.assign 向组件传递props 时,目标是{ foo: "overridden" },源是o。由于目标和源中都存在foo,因此目标中的foo 被覆盖。这也适用于:

      <MyComponent {...o} foo="overridden">
      
      </MyComponent>
      

      在这里,JSX 被转译为相反的:

      React.createElement(MyComponent, _extends({}, o, { foo: "overriden" }));
      

      这有点不同,因为这里的目标是一个空对象,但来自 MDN 的后半段引用适用。这里的来源是o{ foo: "overridden" }。由于foo 存在于两个源中,源{ foo: "overridden" } 中的foo 将覆盖foo 中的o

      【讨论】:

        【解决方案3】:

        查看这个沙盒证明:

        https://codesandbox.io/s/Q1GMx9KM9

        如您所见,它的行为与您在问题中的理论完全一致。

        编辑 SO片段:

        class MyComponent extends React.Component {
          render() {
            return <div>{this.props.foo}</div>
          }
        }
        
        const styles = {
          fontFamily: 'sans-serif',
          textAlign: 'center',
        };
        
        const o = { foo: 'bar' };
        
        const App = () =>
          <div style={styles}>
            <h2>Spreading after explicit property</h2>
            <MyComponent foo="will be overriden" {...o} />
            <h2>Spreading before explicit property</h2>
            <MyComponent {...o} foo="was overriden" />
          </div>;
        
        ReactDOM.render(<App />, document.getElementById('root'));
        <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
        <div id="root"></div>

        【讨论】:

        • 感谢您提供可运行的实现。运行你的代码比阅读整个讨论更有帮助:)
        猜你喜欢
        • 2014-08-06
        • 2018-01-09
        • 2017-11-18
        • 2012-06-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-03-14
        相关资源
        最近更新 更多