React props

一、props用法

来源

组件的属性可以接受任意值,字符串、对象、函数等等都可以。有时,我们需要一种机制,验证别人使用组件时,提供的参数是否符合要求

1、PropTypes

组件类的PropTypes属性,就是用来验证组件实例的属性是否符合要求。

<script type="text/jsx">
    var MyTitle = React.createClass({
        getDefaultProps: function () {
            return {
                title: "duang duang duang!"
            }
        },
        propTypes: {
            title: React.PropTypes.string.isRequired
        },
        changeProp: function(){
            this.setProps({title: 'qqli test'});
        },
        render: function () {
            return (
                <div>
                    {this.props.title}
                    <button type="button" onClick={this.changeProp}>改变title prop</button>
                </div>
            )
        }

    });

    //var data = {};
    //var data = 123; //Warning: Failed propType: Invalid prop `title` of type `number` supplied to `MyTitle`, expected `string`.
    var data = 'string';
    //React.render(<MyTitle title={data} />, document.getElementById("demo"));
    React.render(<MyTitle />, document.getElementById("demo"));
</script>

上面的Mytitle组件有一个title属性。PropTypes 告诉 React,这个 title 属性是必须的,而且它的值必须是字符串。

现在,我们设置 title 属性的值是一个数值。这样一来,title属性就通不过验证了。控制台会显示一行错误信息。

2、默认 Prop 值 getDefaultProps

该方法可以用来设置组件属性的默认值。

var ComponentWithDefaultProps = React.createClass({
  getDefaultProps: function() {
    return {
      value: 'default value'
    };
  }
  /* ... */
});

当父级没有传入 props 时,getDefaultProps() 可以保证 this.props.value 有默认值,注意 getDefaultProps 的结果会被 缓存。得益于此,你可以直接使用 props,而不必手动编写一些重复或无意义的代码。

3、单个子级

React.PropTypes.element 可以限定只能有一个子级传入。

var MyComponent = React.createClass({
  propTypes: {
    children: React.PropTypes.element.isRequired
  },

  render: function() {
    return (
      <div>
        {this.props.children} // 有且仅有一个元素,否则会抛异常。
      </div>
    );
  }

});

4、setProps

setProps(object nextProps[, function callback])

在同一个节点上再次调用 React.render() 来更新根组件是首选的方式,也可以调用 setProps() 来改变组件的属性,触发一次重新渲染。另外,可以传递一个可选的回调函数,该函数将会在 setProps 完成并且组件重新渲染完成之后调用。

该方法仅在根组件上面调用。也就是说,仅在直接传给 React.render() 的组件上可用,在它的子级组件上不可用。如果你倾向于在子组件上使用 setProps(),不要利用响应式更新,而是当子组件在 render() 中创建的时候传入新的 prop 到子组件中。

5、replaceProps

replaceProps(object nextProps[, function callback])

类似于 setProps(),但是会删除所有已存在的 props,而不是合并新旧两个 props 对象。

6、props传递

来源

A、手动传递

大部分情况下你应该显式地向下传递 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 999
    </FancyCheckbox>,
    document.getElementById("demo2")
);

但 name 这个属性怎么办?还有 title、onMouseOver 这些 props?

B、在 JSX 里使用 … 传递

有时把所有属性都传下去是不安全或啰嗦的。这时可以使用 解构赋值 中的剩余属性特性来把未知属性批量提取出来。列出所有要当前使用的属性,后面跟着 …other。

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

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

var FancyCheckbox2 = React.createClass({
    render: function () {

        var { checked,  ...other } = this.props;
        var fancyClass = this.props.checked ? 'FancyChecked' : 'FancyUnchecked';
        // `other` 包含 { onClick: console.log } 但 checked 属性除外

        return (
            <div {...other} className={fancyClass} />
        )
    }
});

React.render(
    <FancyCheckbox2 checked={true} onClick={console.log.bind(console)}>
        Hello world 99999
    </FancyCheckbox2>,
    document.getElementById("demo3")
);

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

7、可检测的类型

React.createClass({
  propTypes: {
    // 可以声明 prop 为指定的 JS 基本类型。默认
    // 情况下,这些 prop 都是可传可不传的。
    optionalArray: React.PropTypes.array,
    optionalBool: React.PropTypes.bool,
    optionalFunc: React.PropTypes.func,
    optionalNumber: React.PropTypes.number,
    optionalObject: React.PropTypes.object,
    optionalString: React.PropTypes.string,

    // 所有可以被渲染的对象:数字,
    // 字符串,DOM 元素或包含这些类型的数组。
    optionalNode: React.PropTypes.node,

    // React 元素
    optionalElement: React.PropTypes.element,

    // 用 JS 的 instanceof 操作符声明 prop 为类的实例。
    optionalMessage: React.PropTypes.instanceOf(Message),

    // 用 enum 来限制 prop 只接受指定的值。
    optionalEnum: React.PropTypes.oneOf(['News', 'Photos']),

    // 指定的多个对象类型中的一个
    optionalUnion: React.PropTypes.oneOfType([
      React.PropTypes.string,
      React.PropTypes.number,
      React.PropTypes.instanceOf(Message)
    ]),

    // 指定类型组成的数组
    optionalArrayOf: React.PropTypes.arrayOf(React.PropTypes.number),

    // 指定类型的属性构成的对象
    optionalObjectOf: React.PropTypes.objectOf(React.PropTypes.number),

    // 特定形状参数的对象
    optionalObjectWithShape: React.PropTypes.shape({
      color: React.PropTypes.string,
      fontSize: React.PropTypes.number
    }),

    // 以后任意类型加上 `isRequired` 来使 prop 不可空。
    requiredFunc: React.PropTypes.func.isRequired,

    // 不可空的任意类型
    requiredAny: React.PropTypes.any.isRequired,

    // 自定义验证器。如果验证失败需要返回一个 Error 对象。不要直接
    // 使用 `console.warn` 或抛异常,因为这样 `oneOfType` 会失效。
    customProp: function(props, propName, componentName) {
      if (!/matchme/.test(props[propName])) {
        return new Error('Validation failed!');
      }
    }
  },
  /* ... */
});

二、在样式props中快速制定像素值

来源

当为内联样式指定一个像素值得时候, React 会在你的数字后面自动加上 “px” , 所以下面这样的写法是有效的:

var divStyle = {height: 10}; // rendered as "height:10px"

React.render(<div style={divStyle}>Hello World</div>, mountNode);

有时候需要保持CSS属性的独立性。下面是不会自动加 “px” 后缀的 css 属性列表:

columnCount,fillOpacity,flex,flexGrow,flexShrink,fontWeight,lineClamp,lineHeight,opacityorderorphans,strokeOpacity,widows,zIndex,zoom

三、行内样式

来源

在 React 中,行内样式并不是以字符串的形式出现,而是通过一个特定的样式对象来指定。在这个对象中,key 值是用驼峰形式表示的样式名,而其对应的值则是样式值,通常来说这个值是个字符串(了解更多):

var divStyle = {
  color: '#f00',
  backgroundImage: 'url(' + imgUrl + ')',
  WebkitTransition: 'all', // 注意这里的首字母'W'是大写
  msTransition: 'all' // 'ms'是唯一一个首字母需要小写的浏览器前缀
};

return (
   <div style={divStyle}>{this.props.title}</div>
)

样式的 key 用驼峰形式表示,是为了方便与JS中通过DOM节点获取样式属性的方式保持一致(比如 'node.style.backgroundImage')。另外浏览器前缀除了ms以外 首字母应该大写。想必 WebkitTransition 的首字母是“W”就不难理解了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值