一、简介(背景)
本文篇幅较多,建议耐心看完,我相信多少会对你有所帮助!
1.1、概念
它是一个将数据渲染为HTML视图 的js库
1.2、原生js痛点
- 用dom的API去操作dom,繁琐且效率低
- 用js直接操作dom,浏览器会进行大量的回流和重绘
- 原生js没有组件化的编程方案,代码复用性低,哪怕有模块话的概念,但模块化也只能拆解一个个js,对样式和结构也没办法拆解,组件化就相当于3剑客整体拆解,成为一个个的小功能
1.3、React特点
- 采用组件化模式,声明式编码,提高开发效率和组件复用性
- 在React Native中可以用react预发进行安卓、ios移动端开发
- 使用虚拟dom和有些的diffing算法,尽量减少与真实dom的交互,提高性能
二、React初体验
2.1、html中使用react
需求:往div中添加一个h1标签
代码注解:这里涉及到3个库文件,一个react(核心库),react-dom(用于支持react操作dom的)还有一个babel(将jsx语法转成js语法,因为浏览器只能识别js),还有就是script标签中的type需要写成text/babel,因为script标签中要写jsx的语法,这里再说一点,就是你引入了react-dom库,就可以使用ReactDOM变量了,跟以前学习jquery一样,引入jquery文件就可以使用$和jquery是同样的道理
2.1.1、 创建虚拟dom的方式
①使用原生js的方式去写(一般不用)
代码注解:使用原生js来创建虚拟dom时,此时script标签的type就不需要写成text/babel,写成原来的text/javascript就可以了,同时也可以删除babel库了,因为不需要它进行转换,浏览器本身就能识别
②使用jsx语法创建(就是最开始的那种方式)
这里可能会有小伙伴会问,为什么不用js来创建dom呢?我看写起来也还行啊,这是因为你还没见过结构嵌套的情况,当需求改为h1标签内再嵌套一个span标签,你怎么办?是不是后面还得再继续套React.createElement(‘span’,{},‘span内容’) ,那如果继续嵌套呢?是不是废了。。。,所以这里就能看出jsx的好处了,其实babel将jsx转换后的代码就相对于用原生js写的那样,只不过这些不用你写,babel帮你转换
2.1.2、 关于创建的虚拟dom
- 本质上其实就是一个object对象;
- 虚拟dom上的属性比较少,真实dom属性多,因为虚拟dom只在recat内部使用,用不到那么多的属性
- 虚拟dom最终会被react转换成真实dom,呈现再页面上
2.2、JSX语法
- 定义虚拟dom时不要用引号
- 标签中引入js表达式要用{}
- 如果在jsx要写行内样式需要使用style={ {coler:red}}形式
- 样式的类名指定不能写class,要写className;
- 只有一个根标签
- 标签必须闭合
- 标签首字母
①若小写字母开头,则会将该标签转为html同名标签,如果没找到,则会报错;
②若大写字母开头,则会认为是组件,它就会去找对应的组件,如果没找到,就会报组件未定义的错误;
三、React面向组件编程
3.1 安装开发者工具(React Developer Tools )
这里工具的具体安装方式就不多说了,由两种方式,一种是翻墙,直接在chrome浏览的商城去下载,还有一种方式是在浏览器扩展程序中打开开发者模式,然后导入已下载的插件文件即可
3.2 组件的分类
1. 函数式组件(适用于简单组件)
2. 类式组件(适用于复杂组件)
3.3 组件实例对象的三大属性
3.3.1、 state
这里我们用一个小需求来说说state和组件内绑定方法这两个问题,需求:点击文本,改变天气状态
上述图片中的例子这样的写法并不能实现我们的需求,为什么?因为changeWeather方法中打印的this是undefined,不是该weather组件的实例对象,自然也就无法拿到该实例对象上的state等属性,更加不用说去改变state中的状态了。。。那为什么会这样的?原因就写在图中,那我们要怎么处理才能让该方法拿到该组件的实例对象呢?来,看下面。。
在构造函数中加一句这个语句就可以了,那这行代码是什么意思呢?
构造函数中的this永远指向该组件的实例对象,所以=右侧意思就是该组件实例对象自身此时还没有该方法,他就会去原型对象上看有没有,显然这里是有的,然后调用bind方法,该方法做两件事,一、创建一个新的函数;二、函数内的this指向bing()括号中传入的,显然这里是组件实例对象;右侧执行完后,将该方法赋值给了实例对象本身的一个方法名(changeWeather),这样实例对象本身就有一个changeWeather方法了,并且内部this就是组件实例对象,所以此时render中点击调用的那个方法,实际上是this实例对象自身的一个changeWeather方法,而不是写在类中的那个原型对象上的changeWeather方法,我们为了不混淆两个重名的方法,我们区分看一下
好了,接下来我们要做改变状态这件事了,我们要通过react中的内置API(setState方法),不能直接更改state,就像下面这样。
好了,到现在需求已经满足了,但我们要对其简化。。。
上述将state和自定义方法直接写在了类中,这样写的意思就是说,给类组件的实例对象添加了一个state属性和自定义方法,而且这里的自定义方法必须写成箭头函数的形式,因为箭头函数内部是没有this指向