React学习
最近课好少啊,芜湖起飞~
主要的参考资料:
1.React元素渲染
1.1 从官方模板开始
值得注意的是,react启动之后,直接修改代码然后ctrl+s,页面会重新reload,非常的人性化~
我们从零开始,在刚新建好react项目的中可以看到./public/index.html
页面可以看到有个<div id="root"></div>
的节点,我们的react组件其实都是渲染在这个里面的。
我们看到./src/index.js
,其实就是将一个<App />
对象渲染到root
节点上,这个<App />
对象是在./src/App.js
中定义的,通过import
导入进来的。
1 | import React from 'react'; |
可能会对<App />
的样子所迷惑,其实就是一个对象,我们换种方式写可能会更加清楚(下面代码的效果同上)
1 | import React from 'react'; |
这样就非常明了,ReactDOM.render()
方法其实就是接收两个参数,将组件对象渲染到一个DOM节点上。
1.2 尝试自己编写对象
我们大概知道渲染的工作流程,我们就可以编写自己的对象,然后渲染到节点。这个代码非常简单,直接看~
1 | import React from 'react'; |
不过有一点值得注意,这样的JS对象只能有一个根结点,也就是说下面这种写法是不允许的!
1 | let h1 = <h1>hello world</h1><h2>yeah</h2>; |
所以如果有需要我们一般使用<div>
标签括起来:
1 | let h1 = <div><h1>hello world</h1><h2>yeah</h2></div>; |
有时候可能对象比较冗长,为了美观,我们用括号括起来,采用下面这种写法:
1 | let h1 = ( |
1.3 写点高级的对象
成天hello world也太枯燥了叭,我们来实现一个时钟吧!
其实也非常的简单,我们只需要使用JS标准对象Date
获取之间,然后显示即可,当然为了让时钟能够实时更新,所以我们需要使用到间隔函数setInterval()
上代码:
1 | import React from 'react'; |
1.4 函数式组件
上面的时钟还有另外一种实现的方式,就是使用函数式组件,就类似于刚开始官方模板中的App
那样的对象
值得注意的是,函数式组件首字母要大写,然后就能顺利的使用函数式组件了,使用格式<name para = {}/>
,注意不要漏掉了后面的/符号
上代码:
1 | // way2 |
时钟效果和上文1.3相同
2.JSX
React使用JSX替代常规的Javascript,类似于XML的Javascript扩展,相较于JS他有许多是好处
- JSX执行更快,在编译成JavaScript代码后进行了优化
- 更加安全,以为其将变量放在
{}
中,在渲染时会过滤传入的值,确保不会遭受注入攻击 - 编写模板也十分简单快速(没vue快吧^_^)
但是也有一些值得注意的地方
- JSX必须要有根节点
- 正常的HTML元素要小写,大写会被认为是组件
2.1 jsx表达式{}
2.1.1 放变量
这个比较简单,前面我们也有使用过
1 | import React from 'react'; |
2.1.2 放表达式
注意只能放入一个表达式
1 | import React from 'react'; |
2.1.3 放HTML标签
1 | import React from 'react'; |
2.1.4 放入CSS样式
新建一个css文件:
1 | .beRed{ |
然后在JS文件中使用
1 | import React from 'react'; |
这样就加入了样式
但是只能注意的是尽量使用className
,因为class
也是JS的一个关键字
2.1.5 注释
在对象中注释也是需要用{}
1 | let h1 = ( |
3.React样式
除了使用css样式,我们也可以使用React的样式,但是React样式必须使用驼峰法,比如borderBottom
,和css不一致,用起来很不方便T_T,算了吧,还是用css吧~
1 | import React from 'react'; |
4.React组件
4.1 函数式组件
这个我们前面已经使用过了, 函数式组件又被称为静态组件,因为其没有状态或者生命周期可言
我们来看一个嵌套的函数式组件
1 | import React from 'react'; |
4.2 类组件
4.2.1 类组件传参
类组件又被称为动态组件,这里我感觉学的还是比较浅,之后再加一些高级的功能吧~这里只是简单的用了一下类组件
值得注意的是,传参后,类组件内使用this.props
获取参数
1 | import React from 'react'; |
4.2.2 类组件状态
温馨提示:想直接看正确操作请跳到最后
样例1 时钟
类组件的状态就类的属性,比如我们仍然希望实现一个时钟页面,我们就能用一个属性来存储时间,然后我们可能就会写出如下代码:
1 | import React from 'react'; |
然而我们会发现我们的时钟并不会动,这也能够理解,因为只渲染了一次嘛,于是我们心中萌生了一个想法,使用setInterval()
多次渲染就可以了,恰巧React类中有一个生命周期函数componentDidMount()
,会再类组件完成渲染后调用,于是我们又会写出如下的代码:
1 | import React from 'react'; |
很不巧的是,我们会发现时钟还是没有动起来,这时候我们才醒悟过来,类的属性值可能一直都没有修改,于是我们又会写出如下的代码:
1 | import React from 'react'; |
但是此时系统又温馨的提示我们不要直接修改state
,而使用setState()
函数
于是我们终于修改好了,并且发现此时甚至不需要我们手动重新渲染整个页面了,妙啊~
1 | import React from 'react'; |
并且我们使用setState()
时其并不是立马修改DOM中的内容,而是修改虚拟DOM,等setState()
执行完后,再对比虚拟DOM和DOM中的内容,再做统一修改,提高效率(不知比之前重新渲染页面效率要高多少~)
样例2 列表切换
列表切换我们就需要做到两个标签的显示于隐藏,我们就能使用类组件中的状态来实现,这里面有许多的细节,但是代码中也是做了比较详细的注释,直接上代码吧
1 | import React from 'react'; |
4.2.3 类组件父传子
其实就是我们普通的传参方式,将参数传入到子元素,控制子元素的状态(其中状态再父元素中保存)
直接上代码:
1 | import React from 'react'; |
实现效果,按钮控制元素显示
4.2.4 类组件子传父
有时候我们也有需要修改父元素的需要,但是通过参数传入父元素的this.state
的值并不能完成修改,但是我们还要其他的方式,可以通过参数传入父元素的函数,然后子元素调用这个父元素的函数就能完成对父元素的修改了,其实思路也是非常简单。
我们用如下一个简单的栗子说明一下吧,做了详细的注释~
1 | import React from 'react'; |
点击按钮就能建文本输入框中的字符串传给父元素了~
5.React事件
React事件和html原生事件还要有一些区别的
- 绑定事件的命名使用驼峰命名法(小驼峰)
- 使用
{}
传入一个函数,而不是字符串 - 事件对象,React返回的事件对象是代理的原生事件对象,如果想要查看事件对象的具体值,必须直接输出事件对象的属性
- 代理对象也不能直接通过return flase阻止默认行为,但是能过通过调用函数解决(
e.preventDefault()
)。 - 传入参数最好使用箭头函数,匿名函数需要进行绑定this
1 | import React from 'react'; |
可以看到返回的事件对象并不能看到事件的具体值
6.React列表渲染
我们可能有需要将一个数组中的内容渲染在页面中,这时候我们可能就需要用到列表渲染了
6.1 弟中弟版本
我们首先试试直接将数组放置在页面中会怎么样?
1 | import React from 'react'; |
可以看到就是简单粗暴的一个一个展开
显然这不是我们想要的效果,聪明的我们立马就想到了,只需要将数组中的元素变成一个一个的JSX对象不就可以了吗?good idea!
1 | let arr = [<li>Alice</li>,<li>Jack</li>,<li>Bob</li>]; // 待显示的数组 |
6.2 弟弟版本
如果我们初始的数组内不是一个一个的JSX对象呢?
那没办法,那就一个一个处理吧~
于是就有了下面的弟弟版本
1 | import React from 'react'; |
6.3 函数版本
如果我们需要渲染的是一个静态列表,那么我们完全可以用函数式组件实现,这里实现和6.2一样的效果
1 | import React from 'react'; |
6.4 类版本
有时候我们可能渲染的列表不是一个静态的内容,可能是一个动态的内容,这时我们就可以使用类组件进行渲染
1 | import React from 'react'; |
这样就为做了一个动态的列表(虽然就是一个小弹窗)
7. React入门项目:肺炎数据统计
现成的数据可以在这取:
肺炎数据可以从各个统计网页获得,这里就跳过了
然后就直接上代码吧,其实没有用到什么新的东西,就是一个列表渲染,当然可以选择多种渲染方式(函数组件、类组件都是OK的),这个比较简单,直接看代码也比较轻松~
1 | import React from 'react'; |
显示的效果:
8.生命周期
生命周期就是组件从实例化到渲染到最终页面中销毁,整个过程就是生命周期,在这生命周期中,我们有许多可以调用的事件,也俗称为钩子函数。
生命周期的3个状态:
- Mounting:(挂载状态),将组件插入到DOM中
- Updating:(更新),将数据更新到DOM中
- Unmounting:(卸载),将组件移出DOM
生命周期的钩子函数:
- componentWillMount 在渲染前调用
- componentDidMount : 在第一次渲染后调用
- componentWillReceiveProps 在组件接收到一个新的 prop (更新后)时被调用。
- shouldComponentUpdate 返回一个布尔值。在组件接收到新的props或者state时被调用。在初始化时或者使用forceUpdate时不被调用。
可以在你确认不需要更新组件时使用。 - componentWillUpdate在组件接收到新的props或者state但还没有render时被调用。在初始化时不会被调用。
- componentDidUpdate 在组件完成更新后立即调用。在初始化时不会被调用。
- componentWillUnmount在组件从 DOM 中移除之前立刻被调用。
我们直接看一个简单的例子就能很快了解这些钩子函数
我写了两个组件,通过母组件调用子组件完成了上述钩子函数的演示,代码非常通俗易懂
1 | import React,{Component} from 'react'; |
然后生成的页面就如下图所示,然后依次按照顺序点击,就能够看到钩子函数的调用顺序了
如下就是钩子函数的调用情况:
9. 中国肺炎疫情小项目
使用前面入门小项目的数据,然后完成一个较为完整的疫情项目(其实非常的简单),算是最近学习的一个总结(准备跑路~),代码链接
最终项目效果:
主要有三个功能组件:
- 地图组件:用于显示中国地图以及相关数据
- 搜索组件:用于搜索相关省份的疫情信息,支持子串搜索
- 表格组件:将疫情数据按照感染人数排序的一个表格信息