1.React的特点
- 采用组件化模式、声明式编码,提高开发效率及组件复用率。
- 在React Native中可以使用React语法进行移动端开发
- 使用虚拟DOM+优秀的Diffing算法,尽量减少与真实DOM的操作
2.为什么React要使用JSX而不使用JS呢?
- JSX 创建虚拟DOM的方式为
const VDOM = <h1>Hello,React</h1>
// 浏览器页面就会显示Hello,React
- JS创建虚拟DOM的方式为
// 这种方式就是使用React的JS方式创建虚拟DOM 页面上也显示Hello,React
const VDOM = React.createElement('h1',{id:'test'},'Hello,React')
- 那么使用JSX相比较于JS的方式创建虚拟DOM的方式的优点在哪里?
- 从这两种方式来看好像没有什么区别 而且使用JSX的方式还会多了一个babel编译的过程
以下: - 使用JSX创建虚拟DOM
// 若需要创建的虚拟DOM是这样的 多嵌套了一层span
const VDOM = (
<h1>
<span>Hello,React</span>
</h1>
)
- 使用JS的方式创建虚拟DOM
// 由于第三个参数只能是内容体 所以需要使用React重新创建VDOM
const VDOM = React.createElement('h1',{id:'test'},
React.createElement('span',{},'Hello,React'))
- 结论分析:如果有很多层级的DOM那就要调用React.createElement很多次 这样写起来会很麻烦。 所以JSX的方式更优。而且JSX通过babel编译之后就会变成下面的那种JS的写法的方式。换句话来说,JSX的方式就是JS的方式的语法糖
3.虚拟DOM和真实DOM的区别?
- 首先虚拟DOM是什么?
- 通过打印出虚拟DOM可以看到,虚拟DOM就是一个Object类型的对象。
- 真实的DOM也是一个对象 上面挂载了很多的属性 虚拟DOM上挂载的属性较少 因为虚拟DOM是React内部在使用 无需那么多的属性
- 虚拟DOM最终会被React转化成真实的DOM 呈现在页面上
4.JSX的语法规则
1.定义虚拟DOM时,不要写引号
2 标签中混入JS表达式时要用{}
3 样式的类名指定不要用class 要用className
4 内联样式 要用style={{key:value}}的形式去写
5 虚拟DOM必须只有一个根标签
6 标签必须闭合
7 标签首字母
7.1 若小写字母开头,则将该标签转化成html中的同名元素 若html没有同名元素 则报错
7.2 若大写字母 react则去渲染对应的组件 若组件没有定义 则报错
5.React 定义组件的两种方式
5.1 函数式组件
// 1.创建函数组件
function MyComponent() {
console.log(this) // undefined 一般情况下this应该是window 这里为什么是undefined
<!--因为babel编译是严格模式下进行的 严格模式下的this是undefined-->
return <h1>创建函数式组件</h1>
}
<!--开发者并没有去调用该函数,那么该函数是谁去调用执行的呢?是React去调用执行的。-->
<!--渲染组件到页面-->
ReactDOM.render(<MyComponent />,document.getElementById('test'));
5.2 类式组件
// 1.创建类式组件
class MyComponent extends React.Component {
render() {
<!--render函数是React.Component原型上的函数 -->
console.log(this)
return <h2>类定义的组件(适用于【复杂组件】的定义)</h2>
}
}
// 2. 渲染组件到页面
ReactDOM.render(<MyComponent />,document.getElementById("test"))
5.2.1 关于类式函数的几个问题
1. render函数是放在哪里的?
- React函数是放在MyComponent的原型上 供实例使用的
2.render中的this是什么?
- render中的this是MyComponent的实例对象
3.执行了Render.render之后发生了什么?
- React找到了组件标签找到Component组件
- 发现该组件是类定义的,然后new出来该类的实例 使用实例调用原型上的render方法
- 将render返回的虚拟DOM转为真实的DOM 呈现在页面中**
6.React中的三大属性
6.1 React中的state属性
- state是组件实例上的一个属性,因此只能是在类式组件中。
Class Weather extends React.Component {
constructor(props) {
super(props)
this.state = {"isHot":true}
}
render() {
const {isHot} = this.state
return <h1 onClick={demo}>今天天气很{isHot?'炎热':'凉爽'}</h1>
}
function demo() {
alert('AAA')
}
}
6.1.1 React中的关于state函数应该注意的问题
为什么要写构造器? 为什么之前不需要些构造器?为什么现在讲到state就要写构造器了?
- 因为构造器中可对组件实例进行初始化的操作,之前的时候没有需要对组件初始化操作的场景。
那么我们需要对组件初始化的时候做什么操作呢
- 因为我们需要用到state来记录状态信息的。但是state一开始的时候为null。 我们可以在构造函数中初始化的时候赋我们想要的值
绑定点击事件的时候的写法差异
- 原生的绑定点击事件就是onclick 在React中就是onClick 绑定其他的事件也是这样的
绑定点击事件的时候带括号和不带括号的差异
-
如果onClick={demo} 就是把demo函数的函数体赋值给点击事件
-
如果onClick={demo()} 就是把demo()函数执行之后的返回值赋值给点击事件
7. 类中方法的this
class Weather extends React.Component {
constructor(props) {
super(props);
this.state = {isHot: true}
}
render() {
const {isHot} = this.state
return <h1 onClick={this.demo}>今天天气很{isHot?'炎热':'凉爽'}</h1>
}
}
demo() {
const {isHot} = this.state
}
- 这种方式的demo都不在组件的内部 demo中的this上没有state demo中的this和组件中的this不一致
那么将demo移到组件里面去呢?
class Weather extends React.Component {
constructor(props) {
super(props);
this.state = {isHot: true}
}
render() {
const {isHot} = this.state
return <h1 onClick={this.demo}>今天天气很{isHot?'炎热':'凉爽'}</h1>
}
demo() {
const {isHot} = this.state
}
}
然后又报错了 为什么报错?
- onClick接收到的是demo函数的函数体,demo又是类中的函数,函数执行不是通过实例调用的,是window直接去调用的,类中的函数会默认开启严格模式,开启严格模式的函数不会指向window。那么就是undefined。 所以就会报错了.
8.setState的使用
- this.state = false; 可以及时更新数据,但是不会更新视图
- 严重注意更新状态一定要使用setState,视图才会随着数据的更新而更新
this.setState({
isHot: !isHot
})
8.1 setState的状态是更新还是合并?
更新。不是替换
8.2 由于数据的更新,视图不断的更新的过程,构造器会调用几次?
- 1次。 组件只new一次 所以就调用一次
8.3 render调用几次?
- 1+n次
- 1次是初始化的那次,n是状态更新的次数