组件的创建
创建组件的第一种方式
- 用构造函数的方式创建组件,之后再将构造函数名以html形式引入
- 组件必须有返回值,若无返回值,则返回null
- 首字母必须大写,因为react是以大小写区别组件和普通html标签,若是遇到大写标签,则当作组件
//定义组件
function Hello(props) {
return 123
}
//渲染
ReactDOM.render(<div>
<Hello></Hello>
</div>, document.getElementById('app'))
- 向组件传递参数构造函数参数列表传入props,用于接受外部数据
- props是只读的,不能修改其值,对象用展开运算符传递简化数据传递
- …obj是ES6的展开运算符,将对象中每个属性传递
function Hello(props) {
return <div>name----{props.name}
<h1>-{props.age}</h1>
<h1>-{props.gender}</h1>
<h1>-{props.address}</h1>
</div>
}
const name='Mary'
const preson ={
age:18,
gender: '男',
address: '西安'
}
//渲染
ReactDOM.render(<div>
<Hello name={name} {...preson}></Hello>
</div>, document.getElementById('app'))
将组件单独抽离将组建抽离为.jsx文件
/****************************在Hello.jsx文件中*****************/
const React = require('react')
//定义组件
export default function Hello(props) {
return <div>name----{props.name}
<h1>-{props.age}</h1>
<h1>-{props.gender}</h1>
<h1>-{props.address}</h1>
</div>
}
/************************************在index.js中导入******************/
import Hello from './component/Hello.jsx'//之后可正常使用
未配置webpack后缀名时,导入不可省略.jsx
后缀名
配置webpack可省略后缀名
在```webpack.config.js``文件中增加如下属性
resolve:{
extensions: ['.js', '.jsx', '.json']//表示,这几个文件的后缀名可省略不写,webpack会依次补全,查找文件,默认情况下只补全.js、.json
}
**
创建组件class的使用
ES6中class是面向对象编程
class关键字内部,还是用原型等创建的,class关键字称之为语法糖,
对用户友好而已
class关键字示例
class Animal {
//每个类中都有一个构造器,如果步手动指定,则默认生成类似于constructor(){}
//构造器的作用是,每当new这个类时,必然会优先执行构造器中代码
constructor(name, age){
this.name = name
this.age = age
}
/**
* 静态属性:通过构造函数直接访问的属性叫做静态属性
* 直接挂载给构造函数,为通过this绑定给实例
* 在class中通过static修饰的属性称为静态属性 通过类.属性访问
*/
static info = 123
//实例方法,挂载在原型上,类似于Animal.prototype.jiao = function(){}
jiao(){
console.log('动物的实例方法')
}
//静态方法,未挂载到原型上,挂载到构造器上
static show(){
console.log("这是静态方法")
}
}
const d = new Animal('wowo', 4)
//通过new出来的实例访问的属性,叫做实例属性
console.log(d.name)
d.jiao()
//静态属性
console.log(Animal.info)
Animal.show()
/********class还是以下方式创建*****/
function Person(name, age){
this.name = name
this.age = age
}
Person.prototype.say()= function(){}
Person.info = 'qq'
Person.show() = function(){}继承class Person{
constructor(name.age){
this.name = name
this.name = age
}
sauHello(){
console.log('大家好')
}
}
/*****************继承*****************/
/**
super
-如果一个子类通过extends继承了父类,那么如果在子类中重新定义constructor(),则必须优先调用super()
-super时一个函数,他是父类中的构造器,子类中super其实就是父类中constructor的一个引用 constructor(name.age)
-调用时必须传入父类构造器中参数
*/
class Chinese extends Person{
constructor(name,age,ID){
super(name,age )
this.id = ID
}
}
class Amercan extends Person{}
const p1 = new Chinese('张三',23,'132*********')
基于class关键字创建组件
- 最基本的组件结构
- 使用在组件内部,this表示实例对象
//继承React.Component则我们定义的类会有组件的特性
class 组件名称 extends React.Component{
//必须有render函数
render(){
//render函数中必须返回合法的JSX虚拟DOM结构
return <div>这是class创建的组件</div>
}
}
//渲染
ReactDOM.render(<div>
<!--此处相当于组件的类的一个实例对象-->
<组件名称></组件名称>
</div>, document.getElementById('app'))const React = require('react')
抽离组件
export default class Helloclass extends React.Component{
constructor(){
//由于helloclass组件继承了React.Component这个父类,所有,自定义构造函数中,必须调用super()
super()
//只用调用super之后,才能使用this关键字
this.state = { //这个this.state={} 就相当于Vue中data(){return{}}
msg:'hello, 我是class中组件'
}
}
//渲染当前组件对应的虚拟DOM
render(){
//该数据可修改
this.state.msg = '-------------'
return <div>class创建的组件
<h2>{this.state.msg}</h2>
</div>
}
}
- 两种创建组件方式对比
- 使用class关键字创建的组件,有自己的私有数据(this.state) 和 生命周期函数;
- 使用function 创建的组件,只有props,没有自己的私有数据和生命周期函数
- 使用构造函数创建出来的组件:叫做“无状态组件”
- 使用class关键字创建出来的组件:叫做“有状态组件”无状态组件
- 由于没有自己的state 和生命周期函数,所以运行效率比有状态组件高
- 有状态组件和无状态组件之间本质区别是:
- 有无state属性,和有无生命周期函数
- 组件中的props和state/data之间的区别
- props中的数据是外界传递过来的
- state/data中的数据,是组件私有的
- props中数据是只读的
- state/data中数据,都是可读可写的