React 之props属性

React 里有一个非常常用的模式就是对组件做一层抽象。组件对外公开一个简单的属性(Props)来实现功能,但内部细节可能有非常复杂的实现。

可以使用JSX 展开属性来合并现有的 props 和其它值:

return <Component {...this.props} more="values" />;

如果不使用 JSX,可以使用一些对象辅助方法如 ES6 的Object.assign或 Underscore_.extend

return Component(Object.assign({},this.props,{ more: 'values' }));

下面的教程介绍一些最佳实践。使用了 JSX 和 ES7 的还在试验阶段的特性。

手动传递

大部分情况下你应该显式地向下传递 props。这样可以确保只公开你认为是安全的内部 API 的子集。

var FancyCheckbox = React.createClass({
  render: function() {
    var fancyClass = this.props.checked ? 'FancyChecked' : 'FancyUnchecked';
    return (
      <div className={fancyClass} onClick={this.props.onClick}>
        {this.props.children}
      </div>
    );
  }
});
React.render(
  <FancyCheckbox checked={true} onClick={console.log.bind(console)}>
    Hello world!
  </FancyCheckbox>,document.getElementById('example')
);

name这个属性怎么办?还有titleonMouseOver这些 props?

在 JSX 里使用...传递

有时把所有属性都传下去是不安全或啰嗦的。这时可以使用解构赋值中的剩余属性特性来把未知属性批量提取出来。

列出所有要当前使用的属性,后面跟着...other

var { checked,...other } = this.props;

这样能确保把所有 props 传下去,除了那些已经被使用了的。

var FancyCheckbox = React.createClass({
  render: function() {
    var { checked,...other } = this.props;
    var fancyClass = checked ? 'FancyChecked' : 'FancyUnchecked';
    // `other` 包含 { onClick: console.log } 但 checked 属性除外
    return (
      <div {...other} className={fancyClass} />
    );
  }
});
React.render(
  <FancyCheckbox checked={true} onClick={console.log.bind(console)}>
    Hello world!
  </FancyCheckbox>,document.getElementById('example')
);

注意:

上面例子中,checked属性也是一个有效的 DOM 属性。如果你没有使用解构赋值,那么可能无意中把它传下去。

在传递这些未知的other属性时,要经常使用解构赋值模式。

var FancyCheckbox = React.createClass({
  render: function() {
    var fancyClass = this.props.checked ? 'FancyChecked' : 'FancyUnchecked';
    // 反模式:`checked` 会被传到里面的组件里
    return (
      <div {...this.props} className={fancyClass} />
    );
  }
});

使用和传递同一个 Prop

如果组件需要使用一个属性又要往下传递,可以直接使用checked={checked}再传一次。这样做比传整个this.props对象要好,因为更利于重构和语法检查。

 

注意:

顺序很重要,把{...other}放到 JSX props 前面会使它不被覆盖。上面例子中我们可以保证 input 的 type 是"checkbox"

剩余属性和展开属性...

剩余属性可以把对象剩下的属性提取到一个新的对象。会把所有在解构赋值中列出的属性剔除。

这是JSX 命令行工具配合--harmony标记来启用 ES7 语法。

使用 Underscore 来传递

如果不使用 JSX,可以使用一些库来实现相同效果。Underscore 提供_.omit来过滤属性,_.extend复制属性到新的对象。

var FancyCheckbox = React.createClass({
  render: function() {
    var checked = this.props.checked;
    var other = _.omit(this.props,'checked');
    var fancyClass = checked ? 'FancyChecked' : 'FancyUnchecked';
    return (
      React.DOM.div(_.extend({},other,{ className: fancyClass }))
    );
  }
});

相关文章

react 中的高阶组件主要是对于 hooks 之前的类组件来说的,如...
我们上一节了解了组件的更新机制,但是只是停留在表层上,例...
我们上一节了解了 react 的虚拟 dom 的格式,如何把虚拟 dom...
react 本身提供了克隆组件的方法,但是平时开发中可能很少使...
mobx 是一个简单可扩展的状态管理库,中文官网链接。小编在接...
我们在平常的开发中不可避免的会有很多列表渲染逻辑,在 pc ...