[React启蒙系列]React 组件属性
本章由lindazhang102翻译
这一章节讨论组件属性(亦称为props)。
组件属性是什么?
组件属性(props)的功能和 HTML attribute 类似。换句话说, props
为组件提供配置值。例如,下面代码中的 Badge
组件,当它被实例化时,它期望获取一个名为 ‘name’ 的属性。
Babel:
var Badge = React.createClass({
render: function() {
return <div>{this.props.name}{console.log(this.props)}</div>;
}
});
var BadgeList = React.createClass({
render: function() {
return (<div>
<Badge name="Bill" />
<Badge name="Tom" />
</div>);
}
});
ReactDOM.render(<BadgeList />,document.getElementById('app'));
HTML:
<div id="app"></div>
当 <BadgeList>
组件里的 render 函数调用 <Badge>
组件时,name
属性会被添加到 <Badge>
组件中,类似于 HTML 属性被添加到 HTML 元素中 (比如, <Badge name="Bill" />
). 然后 name
属性就可以被Badge
组件使用了(比如,this.props.name
). 这就像 <input>
元素用一个 value 属性就可以展示这个 value 了一样。
还有一种理解组件属性的方法,即这些属性都是组件的配置值。如果你看了之前 non-JSX 版本的代码示例,很明显的,组件属性只是一个对象,作为参数传送给 createElement()
函数(比如,React.createElement(Badge, { name: "Bill"
})。
var Badge = React.createClass({
displayName: "Badge",
render: function render() {
return React.createElement(
"div",
null,
//no props defined, so null
this.props.name
//use passed this.prop.name as text node
);
}
});
var BadgeList = React.createClass({
displayName: "BadgeList",
render: function render() {
return React.createElement(
"div",
null,
React.createElement(Badge, { name: "Bill" }),
React.createElement(Badge, { name: "Tom" })
);
}
});
ReactDOM.render(React.createElement(BadgeList, null),
document.getElementById('app'));
这类似于 props
可以在 React 节点中被直接设置(参见 4.4 和 5.7)。当 createElement()
函数的参数为一个组件定义(比如,Badge
),而不是一个节点时,组件属性在该组件自身中也是可用的(比如,this.props.name
)。
组件属性让重用带有任何属性名的 <Badge>
组件成为可能。
在之前的代码示例中,BadgeList
组件使用了两个 Badge
组件,它们分别带有自己的 this.props
对象 。当一个 Badge
组件被实例化时,我们可以通过控制台输出 this.props
值来确定它是哪一个。
Babel:
var Bar = React.createClass({
render: function() {
return <div></div>;
}
});
var foo;
//store a reference to the instance outside of function
var Foo = React.createClass({
render: function() {
return <Bar>{foo = this}</Bar>;
}
});
var FooInstance = ReactDOM.render(<Foo />,
document.getElementById('app'));
console.log(FooInstance === foo);
//verify return value is reference to Foo instance, logs true
基本上每个 React 组件实例都有一个独特的实例属性,该属性称为 props
,一开始它是个空的 JavaScript 对象。这个空对象可以被父组件用 JavaScript 的 值/ 参数 填充。这些值被该组件使用或传递给子组件。
本节笔记
在 ES5 环境/引擎中,你不能改变
this.props
,因为它被冻结了(比如,Object.isFrozen(this.props) === true;
);this.props
是只读的。
发送组件属性
给组件添加属性值时,必须是在组件被使用的时候,而不是在组件被定义的时候。比如,下面的代码中,Badge
组件首先被定义,然后再给它添加属性。当该组件被使用的时候 name=“Bill"
才被添加上去(比如,<Badge name="Bill" />
被渲染的时候)。
var Badge = React.createClass({
render: function() {
return <div>{this.props.name}</div>;
}
});
ReactDOM.render(<Badge name="Bill" />, document.getElementById('app'));
组件在被调用的时候,不管在哪调用,都可以给它传递属性。
var Badge = React.createClass({
render: function() {
return <div>{this.props.name}</div>;
}
});
var BadgeList = React.createClass({
render: function() {
return (<div>
<Badge name="Bill" />
<Badge name="Tom" />
</div>);
}
});
ReactDOM.render(<BadgeList />, document.getElementById('app'));
本节笔记
组件属性是不可变的,并且组件不能够内部修改从它父级传递过来的属性。如果你一定要改变组件属性,那么该组件就要被重新渲染;不要使用
this.props.[PROP] = [NEW PROP]
这种方式来更改props
.
获取组件属性
一个组件实例可以通过 this
关键字获取任何属性值。比如,在下面的代码中,Badge
通过 this
关键字从 render
配置项中获取 props
(比如,this.props.name
) 。
var Badge = React.createClass({
render: function() {
return <div>{this.props.name}</div>;
}
});
ReactDOM.render(<Badge name="Bill" />,
document.getElementById('app'));
如果你看过转化后的 Javascript (比如,JSX to JS),就没什么难掌握的。
var Badge = React.createClass({
displayName: "Badge",
render: function render() {
return React.createElement(
"div",
null,
this.props.name
);
}
});
ReactDOM.render(React.createElement(Badge,{name:"Bill"}),
document.getElementById('app'));
在上面代码示例中,{ name: "Bill" }
对象连同 Badge
组件一起做为 createElement()
函数的参数。该组件可以从 props
那里了解到它的实例属性值被设置为 { name: "Bill" }
。
本节笔记
this.props
是只读的,不要通过this.props.PROP = ‘foo'
去设置 props。
设置默认组件属性
组件在被定义的时候,可以通过配置 getDefaultProps
来设置默认属性。 如下示例:
Babel:
var Badge = React.createClass({
getDefaultProps:function(){
console.log(this.props); //note this logs undefined
return {name:'John Doe'};
},
render: function() {
return <div>{this.props.name}</div>;
}
});
var BadgeList = React.createClass({
render: function() {
return (<div>
<Badge />
<Badge name="Tom Willy" />
</div>);
}
});
ReactDOM.render(<BadgeList />, document.getElementById('app'));
HTML:
<div id="app"></div>
如果这个组件没有其他的 prop
传递进来的话,this.props
就是默认属性。你可以用上面的代码验证下,即不带 name
属性的 Badge
组件实例使用的是默认属性 'John Doe’。
本节笔记
组件被创建的时候,
getDefaultProps
调用一次并被缓存。组件实例创建之前
getDefaultProps
就运行了,因此在getDefaultProps
里使用this.props
是没用的。由
getDefaultProps()
返回的任何对象可以跨实例共享,但不能被复制。
组件属性不仅仅是字符串
确保要理解一个组件属性可以是任何有效的 JavaScript 值。
如下示例:
Babel:
var MyComponent = React.createClass({
getDefaultProps:function(){
return {
propArray: [],
propBool: false,
propFunc: function(){},
propNumber: 5,
propObject: {},
propString: 'string'
}
},
render: function() {
return (<div>
propArray: {this.props.propArray.toString()}
<br /><br />
propFunc returns: {this.props.propFunc()}
</div>) ;
}
});
ReactDOM.render(<MyComponent propArray={[1,2,3]} propFunc={function(){return 2;}} />,
document.getElementById('app'));
HTML:
<div id="app"></div>
注意当 MyComponent
被创建的时候, propArray
和 propObject
被新值覆盖了。
这里的要点就是当你传递属性值的时候,不要仅局限于传递字符串。
【React启蒙系列文章】
三、[React启蒙系列] React和Babel的基本使用
【您可能感兴趣的文章】
前端圈--打造专业的前端技术会议
为web前端开发者提供技术分享和交流的平台
打造一个良好的前端圈生态,推动web标准化的发展
官网:http://fequan.com
微博:fequancom | QQ群:41378087
长按二维码关注我们
投稿:content@fequan.com
赞助合作:apply@fequan.com