用于构建用户界面的js库
进行数据渲染
1、请求数据 2、处理数据
3、操作DOM(react只关注)
原生js操作dom繁琐、效率低下,浏览器进行大量的重绘重排
原生js没有组件化编码方案,代码复用率低下
react特点:
采用组件化模式、声明式编码
在React Native中可以使用React语法进行移动端开发(js编写ios或者安卓应用)
虚拟DOM和优秀的Diffing算法
React入门
jsx==》js 使用到babel.min.js
...
<body>
<div id = "test">
//引入react核心库
<script type="text/javascript"
src = "../js/react.development.js"></script>
//引入react-dom 用于支持react操作dom
<script type="text/javascript"
src = "../js/react-dom.development.js"></script>
//引入bable 将jsx->js
<script type="text/javascript"
src = "../js/babel.min.js">
</script>
<script type="text/babel">//此处一定要写babel
//创建虚拟dom
const VDOM = (
<h1>Hello,React</h1>
...
)
//不写引号,因为不是字符串
//渲染虚拟dom 虚拟dom 展示容器
ReactDOM.render(VDOM, document.getElementById('test'))
</script>
</div>
</body>
虚拟DOM的两种创建方式
1、上面是用jsx
2、用js创建 不用引入babel
<script>
//创建虚拟dom
const VDOM = React.createElement('h1', (id:'title'), 'Hello,React')
//标签名 id名 内容
//不写引号,因为不是字符串
//渲染虚拟dom 虚拟dom 展示容器
ReactDOM.render(VDOM,document.getElementById('test'))
</script>
//对于标签体中还有标签 js中持续套用React.createElement 十分繁琐
虚拟dom其实就是一个js对象
1、object类型的对象(一般对象)
2、虚拟dom属性较少
3、最终会被转换为真实dom
xml早期用于存储和传输数据
关于通过自定义变量再创建dom
jsx语法规则
1、定义虚拟dom不写引号
2、变量引入用{}
3、样式类名指定不要用class 用classname
4、内联样式要用 style = {{key:value}}的形式去写
5、虚拟dom必须只有一个根标签<div>一个包裹
6、标签必须闭合
7、标签首字母
小写开头,则将标签转为html中同名元素 无则报错
大写开头,react去渲染对应组件 无则报错
给react数组可以自动遍历,对象不可以
js表达式(一个表达式可以产生一个值)与js语句(if、for、switch)
虚拟dom中可以识别表达式
模块与组件
chrom浏览器的官方插件 ->react developer tools
函数式组件
<script type="text/babel">
// 创建函数式组件
function demo(){
return <h2>用函数定义的简单组件</h2>
}
// 渲染节点到页面 要写demo标签
ReactDom.render(<demo/>, decument.getElementById('test'))
// React解析组件标签,找到组件
// 调用函数,虚拟dom转为真实组件
</script>
类的相关知识复习
// 类知识
class Person {
// 构造器方法
constructor(name, age){
this.name = name;
this.age = age;
}
// 一般方法,放在类的原型对象手 供实例使用
// 通过person调用speak时,speak中的this就是person实例
speak(){
console.log('speak')
}
}
//创建一个Student类,继承Person类
class Student extends Person {
constructor(name, age, grade){
//写了构造器一定要写super 调用父类构造器 放在最开始
super(name,age);
this.grade = grade;
}
speak(){
//重写从父类继承的方法
}
}
const p1 = new Person('tom', 19)
// 类中的构造器不是非写不可,当需要对其中属性增加时才写
// 如果a继承了b,且a中含有构造器,则a类要调用super
类式组件
//创建类式组件 适用于负责组件 state
//render中的this输出的是组件的实例对象 包括state
class MyComponent extends React.Component {//继承功劳
render(){
//放在类的原型对象上,供实例使用
return <h1>我是用类定义的组件</h1>
}
}
ReactDom.render(<MyComponent/>,document.getElementById('test'))//已经new了实例了
类式组件实例的三大核心属性
1、state:用来存储需要数据
当使用函数进行数据变更时,需要注意内部的this指针指向
(一般在构造器中通过bind方法先对方法指针进行更改,使其指向实例对象,这样就能够通过this指针获取到os:state中的相关数据值)
响应式状态更改this.setState({对象})
//创建类式组件 适用于负责组件 state
//render中的this输出的是MyComponent的实例对象 包括state 开启严格模式 this只指向内部值域
class MyComponent extends React.Component {//继承功劳
// 构造器只执行 1次
constructor(props){
super(props);
//初始化状态
this.state = {isHot: true};
//改变函数this指向到实例对象 解决changeWeather的指向问题
this.demo = this.changeWeather.bind(this);
}
changeWeather(){
//changeWeather放在Weater的原型对象上
// 由于changeWeather是通过onClick进行的回调,是直接调用,不通过Weather实例调用
// 类中的方法默认开启了局部的严格模式,因此changeWeather中的this指向的是undefined
console.log('点击事件方法')
console.log(this)
const isHot = this.state.isHot;
//!!!状态不可以直接更改,需要使用内置API进行更改(setState),且更新是合并不是替换
// this.state.isHot = !isHot;错误写法
this.setState({isHot:!isHot})
}
// render调用1+n次 修改状态即调用
render(){
//放在类的原型对象上,供实例使用 如何绑定事件
return <h1 onClick = {this.demo}>我是用类定义的组件{this.state.isHot == true? '炎热' : '寒冷'}</h1>
}
}
ReactDom.render(<MyComponent/>,document.getElementById('test'))//已经new了实例了
state的属性必须为一个对象
2、props
展开运算符回顾
不能·展开对象 但是jsx和babel中可以
类型的限定
标签属性进行类型默认性限定(在类外)
props是只读的,直接写到类中可以如此表示(只要类中有两个属性即可)
3、refs
类中构造器可以省略,接不接props,取决于是否希望在构造函数中通过this.props
因此一般定义为回调函数,否则直接使用内联函数会发现需要多次回调
saveInput = (c) =>{
this.input = c;}
<div ref = {this.saveInput}></div>
写内联区别也不大其实,这里可以作为参考
//调用后返回一个容器,该容器可以存储被ref所标识的节点,专人专用
myRef = React.createRef()
//<input ref = {this.myRef}>
不要过度使用ref
包含表单的组件分类:受控组件、非受控组件
受控组件
可以省略ref,类似于vue中的v-model 双向绑定 this.setState()
高阶函数
使用时需注意,saveFormData('')指的是将此函数回调的返回值给onChange方法
使用函数调用的返回值,真正saveFormData调用的返回值
常见的高阶函数:promise、setInterval、arr.map()等等
不用科里化的方法,在写触发事件时通过回调函数,为箭头函数传入值
组件的生命周期(旧)
卸载组件
ReactDOM.unmountComponentAtNode(document.getElementById('id'))
定时器放置位置
render的‘bro’,实例对象自带的函数
组件挂载完毕调用 要记得清空定时器,在组件卸载之前啊
componentDidMount(){}
组件将要卸载调用
componentWillUnmount(){}
初始化更新渲染
render(){}
组件的生命周期(新)
废弃了3个,获取了2个新的
DOM的diffing算法
经典面试题:
1、react/vue中的key有什么作用?
2、为什么遍历列表时,key最好不要用index
key是虚拟dom对象的标识,当状态中的数据发生变化时,react会随之进行更新