第五节:组件与props属性

41 阅读3分钟

组件与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') );

以上述为例:

  1. 首先调用了ReactDOM.render()函数,并传入<Welcome name="/Sara"/>作为参数
  2. React调用Welcome组件,并将JSX接收的属性转换为{name:"Alan"},作为props传入
  3. Welcome组件将<h1>Alan~你好呀!<h1>作为返回值
  4. 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之间属于兄弟组件关系

组件提取

有时为了更好的代码复用,只要组件的适应性强,我们可以尽可能的将组件拆分为更小的组件。拆分以后再通过嵌套完成组件的简化和更好的复用。

组件组织

提取组件在大型项目中能够减少工作量和维护成本。在做项目时可以通过嵌套组织树的形式来组织。

image.png

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>   
}