1,关于虚拟DOM:
- 1,本质是Object类型的对象(一般对象).
- 2,虚拟DOM比较"轻",真实DOM比较"重",因为虚拟DOM是React内不再使用,无需真实DOM上那么多的属性.
- 3,虚拟DOM最终会被React转化为真实DOM,呈现在页面上.
2.渲染虚拟DOM到页面上 注意jsx语法
- 1.定义虚拟DOM时,不要写字符串
- 2.标签中混入js表达式要用{}.
- 3.样式的类名指定不用class要用className,
- 4.内联样式要用style={{key:value}},
- 5.只有一个根标签.
- 6.标签必须必和
- 7.标签首字母
- (1)若小写字母开头则将改标签转为html中同名标签.若html中无改标签对应的同名元素,则报错.
- (2)若大写字母开头.react就去渲染对应的组件,若组件没有定义,则报错.
3.函数式组件和类式组件
1.函数是组建就是一个function
function MyComponent () {
console.log(this) //此处的this是undefined 因为babel编译后开启了严格模式
return <h2> 我使用函数定义的组件(适用于[简单组件]的定义)</h2>
}
ReactDOM.render(<MyComponent />,document.getElementById('test'))
/*
执行了ReactDOM.render(<MyComponent />,document.getElementById('test'))之后发生了
1,React解析组件标签,找到MyComponent组件
2,发现组件是使用函数定义的,随后调用该函数,将返回的虚拟DOM转为真实DOM,随后呈现到页面中.
*/
2.类式实例
/*
总结
1,类中的构造器不是必须写的,要对实例进行一些初始化的操作,如添加制动属性时才写. 如果写了 就要加super(aa,bb)
2,如果A类继承了B类,且A类中写了构造器,呢么A类构造器中的super是必须要调用的.
3,类中所定义的方法,都是放在了类的原型对象上,供实例去使用
*/
// 创建一个Person类
class Person {
//构造器方法
construtor(name, age){
//构造器中的this是谁?==类的实例对象
this.name = name;
this.age = age;
}
//一般方法
speak(){
//speak方法放在哪里了?--类的原型对象上,供实例使用.
//通过Person实例调用speak时,speak的this就是Person实例
console.log(`我叫${this.name},我年龄是${this.age}`)
}
}
//创建一个Student类,继承与Person类
class Student extends Person {
construtor(name, age, grade){
super(name,age)
this.grade = grade
}
//重写speak方法
speak(){
console.log(`我叫${this.name},我年龄是${this.age},我是${grade}年级`)
}
study(){
console.log(`我很努力地在学习`)
}
}
3.组件实例的三大核心属性 state
1.state是组件对象最重要的属性,值是对象(可以包含多个key-value的组合)
2.组件被称为"状态机",通过更新组件的state来更新对应的页面显示(重新渲染组件) 通过setData修改数据
<script type="text/javascript">
//1.创建组件
class Weater extends React.Component{
construtor(props){
super(props)
//初始化状态
this.state = {isHot:false }
}
render(){
//读取状态
const {isHot} = this.state;
return <h1 onClick={demo}>今天天气很{ isHot?'炎热':'凉爽'}</h1>
}
}
//2.渲染组件到页面
ReactDOM.render(<Weater />,document.getElementById('test'))
function demo() {
console.log('标题被点击了')
}
</script>
3.组件被称为"状态机",通过更新组件的state来更新对应的页面显示(重新渲染组件)
注意点:
1)组建中render方法中的this为组件实例对象
2)组件自定义的方法中this为undefined如何解决?
a.强制绑定this:通过函数对象bind()
b.箭头函数
3)状态数据,不能直接修改或更新
核心属性2:props
理解:
1,每个组件对象都会有props属性
2,组件标签的所有属性都保存在props中
作用:
1.通过标签属性从组件外箱组件内传递变化的数据
2.注意:组件内部不要修改props数据
编码操作:
1.内部读取某个属性值
this.props.name
2.对props中的属性值进行类型限制和必要性限制
第一种方式(react v15.5开始已经启用)
Person.propTypes={
name:React.PropTypes.string.isRequired,
age:React.PropTypes.unmber
}
第二种方式(新):
使用prop-types库 进限制(需要引入prop-types)库
Person.propTypes={
name:PropTypes.string.isRequired,
age:PropTypes.unmber
}
3.扩展属性:将对象的所有属性通过props传递
<Person {...person}/>
4.默认属性值
Person.defaultProps={
age:18,
sex:'男'
}
5,组件类的构造函数
constructor(props){
super(props)
console.log(props)//打印所有属性
}
三大核心属性refs与事件处理
1.字符串形式
2…回调函数形式的ref
3.回调ref中回调执行次数的问题
4.createRef的使用
React.createRef调用后可以返回一个容器.该容器可以存储被ref所标识的节点,该容器是"专人专用"
1)通过onXxx属性指定时间处理函数(注意大小写)
a.React使用的是自定义(合成)事件,而不是使用的原生DOM事件===为了更好的兼容性
b.React中的事件是通过事件委托方式处理的(委托给组件最外层的元素)
2)通过event.target得到发生事件的DOM元素对象
注意: 请勿过度使用ref
react的生命周期
1.初始化阶段;由ReactDOM.rennder()触发—初次渲染
1.constructor()
2.getDerivedStateFromProps
3.render()
4.componentDidMount()
2.更新阶段:由组件内部this.setSate()或父组件重新render触发
1.getDerivedStateFromProps
2.shouldComponentUpdate()
3.rebder()
4,getSnapshotBeforeUpdate
5.componentDidUpdate()
3.卸载组件:由ReactDOM.unmountComponentAtNode()触发
1.componentWillUnmount()
重要的钩子
1render:初始化渲染或更新渲染调用
2.compontentDidMount:开启监听,发送ajax请求
3.compontentWillUnmount:做一些收尾工作,如:清理定时器
DOM 的diffing算法:
虚拟DOM的遍历循环的时候 只有不同的才渲染 相同的不进行渲染. 深度循环.