React 语法
React 项目的创建
React 需要安装两个包
- React 用来创建React组件,组件的生命周期等这些东西的
- React-dom 里面主要封装了和DOM操作相关的包,比如,要把组件渲染到页面上
在 React 中,如果要创建DOM元素,只能使用React 提供的 JS API 来创建,不能直接像VUE中那样,手写 HTML元素/
React.createElement()方法:
语法:此方法用于创建 虚拟DOM对象,它接受3个及以上的参数
- 参数一: 是个字符串类型的参数,表示要创建的元素类型
- 参数二:是一个属性对象,表示创建的这个元素上,有哪些属性
<div> title='this is a div' id = 'mydiv'> 这是一个div </div>
var myDiv = React.createElement('div',{title: 'this is a div', id: 'mydiv'}, '这是一个div')
ReactDom.render()方法:
语法:
- 参数1: 要渲染的虚拟DOM元素,不加引号
- 参数2: 要渲染到页面的哪个位置中
ReactDom.render(myDiv, document.getElementById('app'))
注意:参数2和vue不一样,不接受#app这样的字符,而是传递一个原生的DOM对象
JSX 使用
使用JSX需要安装安装相关的语法转换工具
运行 npm i babel-preset-react -D
在更目录的 .babelrc 文件中添加
{
"presets": ["react"]
}
-
在JSX语法中: 如果是HTML标签,就按标签解析,如果有{} 则按照变量解析,在{} 中可以写任何符合JS规范的代码
-
在JSX中,如果要为元素添加Class 属性,因为class在ES6中是关键字,需要用className来代替
-
在JSX中,如果有for属性,因为label中的for属性是关键字,需要用 htmlFor 代替。
-
在JSX创建DOM的时候,必须有唯一的元素包裹起来
-
如果要写注释,需要放到花括号中
{/* 这是注释 */}
React 组件
在React 中,构造函数就是一个最基本的组件,如果想要把组件放到页面上,可以把 构造函数的名称当作组件的名称,以HTML标签的形式引入页面中即可
- React在解析所有的标签的时候,是以标签的首字母来区分的,如果标签的首字母是小写,则按照标签识别,如果首字母是大写则按照组件来识别。
function Abc () {
return <div>
这是一个组件
</div>
}
var test1 = <div>
<Abc></Abc>
</div>
ReactDom.render(test1, document.getElementById('app'))
- 在React 中 组件里面也可以传值
function Abc () {
return <div>
这是一个组件{a}
</div>
}
var a = "zhangsan"
var b = 'lisi'
ReactDom.render(<Abc title='{a}' id='{b}'></Abc>, document.getElementById('app'))
- ...obj 是ES6 中的属性扩散,表示,把这个对象上的所有属性,展开了,放到这个位置。
unction Abc () {
return <div>
这是一个组件
</div>
}
var p = {
name: 'zhangsan',
age: 18,
gendar: '男',
address: '北京'
}
ReactDom.render(<Abc {...p}></Abc>, document.getElementById('app'))
- 在组件中,如果想要使用外部传递过来的数据,显示在 构造函数参数列表中,定义props 属性来接受
function Abc (props) {
return <div>
这是一个组件 {props.address}
</div>
}
var p = {
name: 'zhangsan',
age: 18,
gendar: '男',
address: '北京'
}
ReactDom.render(<Abc></Abc>, document.getElementById('app'))
- 通过props 得到的任何数据都是只读的,不能够赋值。
ES6 class 关键字
介绍:ES6引入了Class(类)这个概念,作为对象的模板,通过class关键字,可以定义类。基本上,ES6的class可以看作只是一个语法糖,它的绝大部分功能,ES5都可以做到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。上面的代码用ES6的“类”改写,就是下面这样。
在ES5 中我们通常都是用function和prototype来模拟面向对象这个概念
-
class 关键字是ES的新语法,用于创建构造函数
-
class 后面跟上类名,加{}
-
在每个class类内部,都有一个constructor构造器,如果没有显示定义构造器,那么类内部默认都有个看不见的 contructor。 contructor 的作用类似于 之前的
function Hello () {}
-
每当使用new关键词,创建class类实例的时候,必然会优先调用constructor 构造器
// 用 class 关键字创建的构造函数
class Per {
constructor (name,age) {
this.name = name
this.age = age
}
// 给Per这个构造函数的原型添加say方法,其中 say() {} 为ES6语法
say () {
console.log('hello word')
}
// 给原型添加静态属性
static info = 123
// 静态实例方法
static say2 () {
console.log('hello')
}
}
var p2 = new Per('wangwu', 20)
console.log(p2)
// 用一般方法来创建的构造函数
function P1(name, age) {
this.name = name
this.age = age
}
// 给原型添加say 方法
P1.prototype.say = function () {
console.log('你好')
}
// 给原型添加静态属性
P1.info = 123
var p1 = new P1 ('张三', 28)
console.log(P1.info)
实例对象
- 实例对象是只能由构造函数创建出来的实例才能调用它熟悉和方法的对象,构造函数本身不能调用。
- ES6 的实例属性只能在 constructor 中定义
class Per {
constructor (name , age) {
this.name = name
this.age = age
// 实例属性
}
// 实例对象
say () {
console.log('hello')
}
}
var a = new Per ('zs', 18)
console.log(a.say())
静态对象
-
静态对象是只能由构造函数本身来调用,而在实例对象中无法调用的属性和方法
-
静态对象不能被实例继承
-
在ES6 中明确规定只有静态方法没有静态属性
-
静态对象 用 static 来定义
class Per {
constructor (name, age) {
this.name = name
this.age = age
}
static say () {
console.log('hello')
}
}
console.log(Per.say())
ES7有一个静态属性的提案,目前Babel转码器支持。安装babel-preset-stage-0 包含了0-3的stage,可根据需要添加,不同的stage封装了不同的插件,官方推荐是使用stage-1 安装命令(根据自己的需求调整)
//ES7提案 定义静态属性
static lastName = 'pcaca';
//ES7定义实例属性
height = '170cm'
extends 关键词 继承
- extends 实现继承,前面是子类后面是父类
class Chinese extends Person
- 在使用extends 关键词 实现了继承,子类的 constructor 构造函数中,必须用 super ( ) 来表示父类构造函数。
- 父类中的任何东西,子类都能继承到,包括实例方法、属性和静态方法、属性
- 在使用了extends 时,一定要在第一行来调用super(),否则报错
class Person {
constructor(name, age) {
this.name = name
this.age = age
}
}
// extends 实现继承
class Chinese extends Person {
constructor(name,age,say) {
super(name,age)
this.say = say
}
}
var c1 = new Person ('zhangsan',15)
var c2 = new Chinese('lisi',23, '中国')
console.log(c1)
console.log(c2)
React.Component
使用 React.Component 继承的方式新建组件 必须要有 render () { return}
var a = {
name: 'zhangsna',
age: 18,
sex: 'nan'
}
class Hello1 extends React.Component {
constructor (pops) {
super(pops)
console.log(pops)
}
render () {
return <div>
<ul>
<li>{this.props.name}</li>
</ul>
</div>
}
}
ReactDom.render(<Hello1 {...a}></Hello1>, document.getElementById('app'))
this.state 的使用
this.state 表示当前组件实例的私有数据对象,类似于vue中,组件实例身上的data( ) { return} 函数
class Hello1 extends React.Component {
constructor() {
super()
this.state = {
msg: 'message',
data: 'hello'
}
}
render () {
return <div>
<ul>
<li>{this.state.data}</li>
</ul>
</div>
}
}
ReactDom.render(<Hello1></Hello1>, document.getElementById('app'))
React 事件绑定机制
- 在React中,如果想要为元素绑定事件,不能使用网页中传统的onclick 事件,而是需要使用React提供的onClick 来实现。
- React中提供的事件绑定机制,都是使用的驼峰命名,同时传统的JS事件,都被React重新定义了一下,改成了驼峰命名。
- 在React提供的事件绑定机制中,事件的处理函数,必须直接给定一个function ,而不是一个function的名称。
- 在为React绑定处理函数时,需要通过this函数名,来把函数的引用交给事件。
class Hello1 extends React.Component {
constructor() {
super()
this.state = {
name:'123',
data:'123'
}
}
btn () {
console.log('点击事件')
}
render () {
return <div>
<ul>
<li><button onClick={this.btn}>点击</button></li>
</ul>
</div>
}
}
ReactDom.render(<Hello1></Hello1>, document.getElementById('app'))
- 在事件绑定函数中默认会改变this指向,要想让 以上中的 btn 点击事件 能够正确的获取this.state的数据,需要用到箭头函数保证,this指向不被改变。 btn = () => {}
btn = () => {
console.log('点击事件')
}
-
直接使用this.state.msg = 123 直接赋值,虽然可以改变数据,但是页面不会更新。所以不推荐使用这种方法。
this.setState
- 如果要为this.state 上的数据重新赋值,推荐使用React 中的 this.setState({配置对象})来重新为state赋值
btn = () => { console.log('点击事件') this.setState({ msg: 'test' }) }
- this.setState 方法,只会重新覆盖那些显示定义的属性值,如果没有提供最全的属性,则没有提供的属性值,不会被覆盖(按需修改,局部数据)
- this.setState 支持传递 function函数,如果传递的是function 则必须 return一个 对象。
- 在function 的参数中,支持传递两个参数,其中第一参数是preState,表示未修改之前的数据state
- 第二个参数是外界传递给当前组件的props 数据。
- this.setState 在调用的时候,是异步执行的,当立即调用完this.setState 后,输出的state值可能是旧数据。
function 与 class 组件区别
- 使用functon 构造函数的组件,内部没哟state 私有数据,只有一个props 来接收外界传递进来的数据
- 使用class 关键词创建的组件,内部除了有this.props 这个只读属性,还有专门用于存放自己私有数据的 this.state 属性,这个state是可写的。
- 基于以上区别,function的组件叫 无状态组件,class的组件叫做有状态组件
- function 组件没有state属性,也没有生命周期函数,而class组件两者都有。