组件与props属性
函数组件
组件类似于JavaScript函数,他接受任意props
参数,并返回用于描述页面展示内容的React元素。
所以定义组件最简单的方式就是编写JavaScript函数:
function Welcome (props) {
return <h1>{ props.name }~ 你好呀!</h1>
}
解析:
Welcome
组件接收唯一带有数据的props
对象,并根据props
中的数据返回一个react元素- 为了复用,组件需要带一个名字,这里的
Welcome
就是组件名.
注:组件名称必须以大写字母开头,否则会被认为HTML的原生标签
class组件
定义组件的另一种方式是使用ES6的class语法,并继承React的Component
类
class Welcome extends React.Component {
render () {
return <h1>{ this.props.name }~ 你好呀!</h1>
} }
解析:
- 必须的
render
函数:class组件必须提供render函数,并返回一个React元素。用于描述该组件要展示的内容 - 具有额外特性:继承了React.Component类,也让组件具有了额外特性
渲染组件
当React元素是用户自定义的组件时,他会将JSX所接受的属性转换为单个对象props
传递给组件函数。
- 渲染函数组件
function Welcome (props) {
return <h1>{ props.name }~ 你好呀!</h1> }
ReactDOM.render(
<Welcome name="Alan" />,
document.getElementById('app') );
上述示例的props对象是{name:"Alan"}
- 渲染class组件
class组件的props对象会混入每一个组件的实例对象上,需通过
this
访问
class Welcome extends React.Component {
render () {
return <h1>{ this.props.name }~ 你好呀!</h1> } }
ReactDOM.render(
<Welcome name="Alan" />,
document.getElementById('app') );
组件渲染过程
class Welcome extends React.Component {
render () {
return <h1>{ this.props.name }~ 你好呀!</h1>
} }
ReactDOM.render(
<Welcome name="Alan" />,
document.getElementById('app') );
以上述为例:
- 首先调用了
ReactDOM.render()
函数,并传入<Welcome name="/Sara"/>
作为参数 - React调用
Welcome
组件,并将JSX接收的属性转换为{name:"Alan"}
,作为props
传入 Welcome
组件将<h1>Alan~你好呀!<h1>
作为返回值- React DOM将DOM高效更新为
<h1>Alan~你好呀!</h1>
使用组件
组件复用
ReactDOM.render(
<div>
<Blogpost title="我和React" content="在W3CSchool,有一段我和React的邂逅故事" />
<Blogpost title="React博客" content="React创建博客很简单呀" />
<Blogpost title="你的梦想是什么?" content="少年,说出你的故事!我在听" />
</div>,
document.getElementById("app") )
组件可以被无数次的复用,每个组件都有自己的props对象。因为每使用一次组件,就有一个组件的新实例被创建。
组件嵌套
组件可以在其输出中引用其他组件,意味着可以用组件来抽象出任意层次的细节。
class App extends React.Component {
render(){
return (
<div>
<Blogpost title="我和React" content="在W3CSchool,有一段我和React的邂逅故事" />
<Blogpost title="React博客" content="React创建博客很简单呀" />
<Blogpost title="你的梦想是什么?" content="少年,说出你的故事!我在听" />
</div> ) } }
ReactDOM.render( <App />,
document.getElementById("app") )
一般来说只在ReactDOM.render里渲染单个组件,再根据需求自下而上地嵌套组件,逐步应用到视图层的每一处。
组件关系
在上面的例子里,
App组件跟Blogpost组件属于父子组件关系 Blogpost之间属于兄弟组件关系
组件提取
有时为了更好的代码复用,只要组件的适应性强,我们可以尽可能的将组件拆分为更小的组件。拆分以后再通过嵌套完成组件的简化和更好的复用。
组件组织
提取组件在大型项目中能够减少工作量和维护成本。在做项目时可以通过嵌套组织树的形式来组织。
props属性重现
props的传值类型
对组件来说。JSX属性可接受任何类型的值,意味着可以利用props传递任何类型的组件。
- 传一个数字
// 用 {} 表示这是一个 JavaScript 表达式而不是字符串
<Blogpost likes={17} />
// 用一个变量进行动态赋值
<Blogpost likes={post.likes} />
- 传一个布尔值
<Blogpost show={false} />
// 用一个变量进行动态赋值
<Blogpost likes={post.show} />
// 特殊:在 JSX 属性没有值的情况,都意味着布尔值 true
<Blogpost show />
- 传一个对象
// 第一对 {} 表示这是一个 JavaScript 表达式,第二对 {} 表示接收的是对象键值对
<Blogpost
author={{
name: "Han Solo",
avatarUrl: "https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png"
}} />
// 用一个变量进行动态赋值
<Blogpost commentIds={post.author} />
- 传一个数组
// 用 {} 表示这是一个 JavaScript 表达式而不是字符串
<Blogpost commentIds={[234, 266, 273]} />
// 用一个变量进行动态赋值
<Blogpost commentIds={post.commentIds} />
- 传入一个对象的所有属性
const post = {
authorName: "Han Solo",
avatarUrl: "https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png",
likes: 17,
show: true,
commentIds: [234, 266, 273],
};
使用ES6提出的扩展运算符传入post对象中的每一个键值对
<Blogpost {...post} />
props的只读性
React规定:所有React组件都绝不能修改自身的props,始终将props视为组件的配置项而不是组件的数据。
以下为反例:
render(){
this.props.likes = 18; // 此处修改了 props
return <div>{this.props.likes}</div>
}