内容简介:这是一门免费课程,写文章和录制视频这个我花了1个半月时间,如果你觉的不错可以给一个赞。文章和视频中会详细讲解React的基础知识,React版本是16x,也是目前最新版本(我课程录制开始的日期是2019年5月4日)。今年的目标是录制100集前端我们采用最新的React16.8版本进行讲解,我相信很多人应该也会使用React,但是你可能学的并不是很系统,不妨跟着技术胖来一次详细的学习吧。已更新完成........附上文章视频列表。
这是一门免费课程,写文章和录制视频这个我花了1个半月时间,如果你觉的不错可以给一个赞。文章和视频中会详细讲解React的基础知识,React版本是16x,也是目前最新版本(我课程录制开始的日期是2019年5月4日)。今年的目标是录制100集前端 免费视频教程 ,可能大部分都会在React框架上,毕竟它是现在最火的前端框架,也是前端必会的一个框架。
我们采用最新的React16.8版本进行讲解,我相信很多人应该也会使用React,但是你可能学的并不是很系统,不妨跟着技术胖来一次详细的学习吧。
已更新完成........附上文章视频列表。
视频列表
-
React高级-调试 工具 的安装及使用(301)
第01节:React课程前言
很高兴你能来到这里学习React.js技术,这是课程的第一节,主要介绍一下小伙伴们常问的一些问题,虽然废话很多,但是还是建议你可以花几分钟看完这节视频。
技术胖的React交流Q群:159579268
React简介
首先不能否认React.js是全球最火的前端框架(Facebook推出的前端框架),国内的一二线互联网公司大部分都在使用React进行开发,比如阿里、美团、百度、去哪儿、网易 、知乎这样的一线互联网公司都把React作为前端主要技术栈。
React的社区也是非常强大的,随着React的普及也衍生出了更多有用的框架,比如 ReactNative
和 React VR
。React从13年开始推广,现在已经推出16RC(React Fiber)这个版本,性能和易用度上,都有很大的提升。
React优点总结
-
生态强大:现在没有哪个框架比React的生态体系好的,几乎所有开发需求都有成熟的解决方案。
-
上手简单: 你甚至可以在几个小时内就可以上手React技术,但是他的知识很广,你可能需要更多的时间来完全驾驭它。
-
社区强大:你可以很容易的找到志同道合的人一起学习,因为使用它的人真的是太多了。
需要的前置知识
-
JavaScript基础:如果能回ES6就更好了,因为我们尽量在课程中使用ES6的语法编写案例。
-
npm基础:你需要会使用npm的包管理,其实这个不会也没事,反正课程中都会讲解。
讲授方式和学习要领
-
学习这套视频你完全不用记笔记,只要专心的听课,笔记技术胖已经为你准备好了文字版在每个视频下方。
-
代码全部手写:代码全部进行手写,不做PPT式讲解,不做粘贴复制,你只要认真看,肯定学的会,不会有坑让你爬不上来。
-
和3000名小伙伴一起学习: 群已经开放了,你可以直接进入QQ群,大家都是一起学习的,有什么问题可以一起讨论。
视频更新频率
这个视频 每周更新三集 ,所以请小伙伴们收藏本网页,或者进入群学习,只要更新内容,群里都会进行通知。可以保证你及时的学习。
技术胖还是个一线程序员,平时加班也不少,所以有时候会更新不及时,还请大家谅解。
声明:课程借鉴了《 深入浅出React和Redux 》这本书,但也加入了自己的理解,更不会单纯的抄袭本书的任何话语和章节,如果引用本书话语,都会全部标出,以示对版权的尊重(其实我就是看着这本书学习的,然后录制的课程)。
如果你觉的看书更好,可以买一本学习。
加QQ群 一起学习
为了大家能更好的一起学习,技术胖同样也建立了QQ群,如果学习中遇到什么困难,可以进群提问,相信群里有很多人可以为你解答问题。
QQ群 :524520566 (3000人大群,入群请正确回答问题,答案请全部小写)
群里只讨论技术问题,禁止闲聊。
如果你在学习中有什么问题,还可以在文章下方进行留言,技术胖会尽快回复你的问题。
由于个人能力有限,在讲解过程中有不对之处,希望大家能在文章底部进行留言勘误校正,技术胖在先在这里抱手感谢。
第02节:React简介和Vue对比
这节课简单介绍一下React框架,并通过介绍,引出一个争执很多的话题,到底什么时候用 React.js
?什么时候用 Vue.js
?其实这节课也是偏重于理论的,但是我觉的有必要单独拿出来一节课说一说,因为有很多小伙伴还在犹豫,我已经会了Vue,还有没有必要学习React?答案是肯定的,那就是一定要学。因为这套课可能更多的面向新手,所以必要的理论也是不能缺少的。
技术胖的React交流Q群:159579268
React简介
如果你进入官方网站,只会看到一句简单的介绍:
A JavaScript library for building user interfaces (用于构建用户界面的JavaScript库)
就是这样简单的一句话,显得朴实无华,但当我每次看到时都感到它的霸气侧漏,肃然起敬。越是伟大的东西,越让人感到谦卑。
毒鸡汤
作为一个程序员,任何时候,都不要瞧不起别人…鸟活着时,吃蚂蚁;鸟死后,蚂蚁吃鸟。一棵树可以制成一百万根火柴,烧光一百万棵树只需一根火柴。所以不要瞧不起任何人!你瞧不起别人时,只不过别人不和你计较!花,姹紫嫣红,却只是昙花一现: 树,朴素寻常,却可以百岁长青。活着,低调做人。因为作为一名程序员,就算你想高调,你有时间和金钱吗?别做梦了,好好学习吧!
React三大体系
这个学习也是有一个层次的,需要你先学会 React.js
的基本知识,然后再学习 ReactNative
,这样你的学习难度会大大降低。我的目标也是这样的,先讲解 React.js
基础,然后基础打好了,开始学习 ReactNatvie
。所以这个视频的周期还是比较长的,需要你多些耐心的学习。
正式简介
ReactJS
是由Facebook在2013年5月推出的一款JS前端 开源 框架,推出式主打特点式 函数式编程 风格。值得一说的是,到目前为止 ReactJS
是世界上使用人数最多的前端框架,它拥有全球最健全的文档和社区体系。我们这里学习的是 React Fiber
版本,也就是React16这个版本,这个版本算是一个大升级,增加了很多新的特性,这些特性我都会在以后的课程中给大家一点点讲解。
ReactJS的官方网站为:reactjs.org
如果你是英文很好的同学,我建议你一直阅读React官方文档,这个文档我相信一定可以超过80%现在市面上的React书籍,详细程度就更不用多说了,怎么说人家是官方文档,是书籍编写者的写作大纲哦。(包括我的文章,一定不如官方文档好)
React和Vue的对比
这是前端最火的两个框架,虽然说React是世界使用人数最多的框架,但是就在国内而言Vue的使用者很有可能超过React。两个框架都是非常优秀的,所以他们在技术和先进性上不相上下。
那个人而言在接到一个项目时,我是如何选择的那? React.js
相对于 Vue.js
它的灵活性和协作性更好一点,所以我在处理复杂项目或公司核心项目时,React都是我的第一选择。而 Vue.js
有着丰富的API,实现起来更简单快速,所以当团队不大,沟通紧密时,我会选择Vue,因为它更快速更易用。(需要说明的是,其实Vue也完全胜任于大型项目,这要根据自己对框架的掌握程度来决定,以上只是站在我的知识程度基础上的个人总结)
总结
我相信大家通过这节课的学习,对React一定有了一个直观的概念。下节课开始我们就要动手开发了,小伙伴们加油了。
第03节:React开发环境搭建
通过两节课的理论学习,这节终于可以进入操作环节了,其实技术胖早已经迫不及待了。讲理论就放佛认识一个美女,缺只能让你看,剩下啥都做不了一样。了解我的小伙伴都知道,我一定不是这种性格。这节课就让我们一起动手,把React的开发环境搭建好。在搭建React开发环境前需要你安装Node,如果你已经安装了可以省略这些步骤。
技术胖的React交流Q群:159579268
安装Node.js
使用 React.js
是可以用最原始的 <Script>
标签进行引入的,但是这实在是太low了,工作中也不会有这种形式进行引入。所以在学习的时候,我们就采用脚手架形式的安装。这就需要我们安装 Node.js
,用里边的 npm
来进行安装。
安装Node只需要进入Node网站,进行响应版本的下载,然后进行双击安装就可以了。
Node中文网址:nodejs.cn/ (建议你在这里下载,速度会快很多)
需要你注意的是,一定要正确下载对应版本,版本下载错误,可是没有办法使用的哦。
Node.js
安装好以后,如果是Windows系统,可以使用 Win+R
打开运行,然后输入 cmd
,打开终端(或者叫命令行工具)。
输入代码:
node -v 复制代码
如果正确出现版本号,说明Node安装成功了,需要说明的是,你的版本号可能跟我视频中的有所不同,这无关紧要。
然后再输入代码:
npm -v 复制代码
如果正确出现版本号,说明npm也是没问题的,这时候我们的 Node.js
安装就算完成了。
脚手架的安装
Node安装好之后,你就可以使用npm命令来安装脚手架工具了,方法很简单,只要打开终端,然后输入下面的命令就可以了。
npm install -g create-react-app 复制代码
create-react-app
是React官方出的脚手架工具,其实有很多第三方的脚手架工具,也有很多优秀的。但是作为初学者为了减少踩坑,所以我们使用官方的脚手架。
创建第一个React项目
脚手架安装好以后,就可以创建项目了,我们在 D盘
创建一个 ReactDemo
文件夹,然后进入这个文件夹,创建新的React项目。
D: //进入D盘 mkdir ReactDemo //创建ReactDemo文件夹 create-react-app demo01 //用脚手架创建React项目 cd demo01 //等创建完成后,进入项目目录 npm start //预览项目,如果能正常打开,说明项目创建成功 复制代码
其实这些操作只需要再终端中输入就可以了。等到浏览器可以打开React网页,并正常显示图标后,说明我们的环境已经全部搭建完成了。
毒鸡汤亲爱的程序员: 如果你安装失败了,你不要惧怕,毕竟怕啥来啥。 你要相信只要你全力以赴,就没有你搞不砸的事情。
你可以试着换成手机WIFI热点,再来一遍上边的步骤,没准你流量费花了,就安装成功了那。你也可以在群里留言,技术胖会全力帮助你。
总结:这节课开始技术胖希望你能跟着我动手作一作,因为你不动手永远学不会。技术胖没有任何别的目的,真心希望你可以学会。动手把环境搭建好,否则下节课你就没办法练习了。
第04节:脚手架生成的项目目录介绍
用脚手架生成目录后,需要对目录有个基本的认识。最起码知道都是作什么用的,否则我们如何编写程序那?打个比喻:你知道了一个特别好的娱乐场所,你一直很向往,想去体验一把,可是你不了解行情和规矩,那最多你也只能去泡泡澡,吃吃自助餐了。我们现在就是这种情况,所以这节课将带你浏览一下React脚手架生成目录和文件的作用。
技术胖的React交流Q群:159579268
项目根目录中的文件
先从进入项目根目录说起,也就是第一眼看到的文件(版本不同,可能稍有不同)
-
README.md:这个文件主要作用就是对项目的说明,已经默认写好了一些东西,你可以简单看看。如果是工作中,你可以把文件中的内容删除,自己来写这个文件,编写这个文件可以使用
Markdown
的语法来编写。 -
package.json: 这个文件是
webpack
配置和项目包管理文件,项目中依赖的第三方包(包的版本)和一些常用命令配置都在这个里边进行配置,当然脚手架已经为我们配置了一些了,目前位置,我们不需要改动。如果你对webpack了解,对这个一定也很熟悉。 -
package-lock.json:这个文件用一句话来解释,就是锁定安装时的版本号,并且需要上传到git,以保证其他人再
npm install
时大家的依赖能保证一致。 -
gitignore: 这个是git的选择性上传的配置文件,比如一会要介绍的
node_modules
文件夹,就需要配置不上传。 -
node_modules:这个文件夹就是我们项目的依赖包,到目前位置,脚手架已经都给我们下载好了,你不需要单独安装什么。
-
public:公共文件,里边有公用模板和图标等一些东西。
-
src: 主要代码编写文件,这个文件夹里的文件对我们来说最重要,都需要我们掌握。
public文件夹介绍
这个文件都是一些项目使用的公共文件,也就是说都是共用的,我们就具体看一下有那些文件吧。
-
favicon.ico: 这个是网站或者说项目的图标,一般在浏览器标签页的左上角显示。
-
index.html: 首页的模板文件,我们可以试着改动一下,就能看到结果。
-
mainifest.json:移动端配置文件,这个会在以后的课程中详细讲解。
src文件夹介绍
这个目录里边放的是我们开放的源代码,我们平时操作做最多的目录。
-
index.js: 这个就是项目的入口文件,视频中我们会简单的看一下这个文件。
-
index.css:这个是
index.js
里的CSS文件。 -
app.js: 这个文件相当于一个方法模块,也是一个简单的模块化编程。
-
serviceWorker.js: 这个是用于写移动端开发的,PWA必须用到这个文件,有了这个文件,就相当于有了离线浏览的功能。
总结:建议你这节课要看视频进行学习,视频会讲的详细一点,而且更有层次,看文章你可能学不会。
第05节:HelloWorld和组件的讲解
这节课先把 src
目录里的文件全部删除,我们一点点写一个·HelloWorld·程序,并通过编写这个程序了解一下什么是 React
中的组件化编程。
入口文件的编写
写一个项目的时候一般要从入口文件进行编写的,在 src目录
下,新建一个文件 index.js
,然后打开这个文件。
写入下面4行代码:
import React from 'react' import ReactDOM from 'react-dom' import App from './App' ReactDOM.render(<App />,document.getElementById('root')) 复制代码
上面的代码,我们先引入了React两个必要的文件,然后引入了一个APP组件,目前这个组件还是没有的,需要一会建立。然后用React的语法把APP模块渲染到了 root
ID上面.这个rootID是在 public\index.html
文件中的。
这样入口文件就写好了,这时候我们就需要写APP组件了。
app组件的编写
现在写一下App组件,这里我们采用最简单的写法,就输出一个 Hello JSPang
,就可以了。
import React, {Component} from 'react' class App extends Component{ render(){ return ( <div> Hello JSPang </div> ) } } export default App; 复制代码
这里有一个难点,就是:
import React, {Component} from 'react' 复制代码
这其实是ES6的语法-解构赋值,如果你分开写就比较清楚了,你可以把上面一行代码写成下面两行.
import React from 'react' const Component = React.Component 复制代码
如果你对ES6语法不熟悉,你完全可以使用这种形式来进行编写。
当我们这两个文件都编写完成后,可以在终端使用 npm start
命令,来看一下我们编写的结果了。
**总结:**React的主要优势之一就是组件化编写,这也是现代前端开发的一种基本形式。所以我们在学习React的时候就要多用这种思想,只有不断练习,我们才能在工作中得心应手,轻松自如。小伙伴们也动手作一下吧。
第06节:React中JSX语法简介
上节课已经接触到了JSX语法,看起来跟 html
标签几乎一样,事实也是如此。JSX语法确实也有很多需要注意的事项,但是对于初学者学太多反而不好。所以这节课我们作一个最简单的JSX语法介绍。
JSX简介
JSX就是Javascript和XML结合的一种格式。React发明了JSX,可以方便的利用HTML语法来创建虚拟DOM,当遇到 <
,JSX就当作HTML解析,遇到 {
就当JavaScript解析.
比如我们写一段JSX语法
<ul className="my-list"> <li>JSPang.com</li> <li>I love React</li> </ul> 复制代码
比如我们以前写一段代码JS代码:
var child1 = React.createElement('li', null, 'JSPang.com'); var child2 = React.createElement('li', null, 'I love React'); var root = React.createElement('ul', { className: 'my-list' }, child1, child2); 复制代码
从代码量上就可以看出JSX语法大量简化了我们的工作。
组件和普通JSX语法区别
这个说起来也只有简单的一句话,就是你自定义的组件必须首写字母要进行大写,而JSX是小写字母开头的。
这个也算是一个比较重要的知识点吧。
JSX中使用三元运算符
在JSX中也是可以使用js语法的,这节课我们先简单讲解一个三元元算符的方法,见到了解一下。
import React from 'react' const Component = React.Component class App extends Component{ render(){ return ( <ul className="my-list"> <li>{false?'JSPang.com':'技术胖'}</li> <li>I love React</li> </ul> ) } } export default App; 复制代码
总结:通过这节课的简单学习,小伙伴们一定对JSX语法有个简单的了解,其实作为一个初学者,我们先知道这么多就足够了。随着课程以后我们会继续深入讲解。
第07节:React实例-小姐姐服务菜单
通过六节的学习,已经对React有了基本的认识。最好的学习就是在实战中的成长了,我们开始以作一个《小姐姐服务菜单》的应用,练习以前所学的知识和学习新知识。当然这个视频不是教大家作CSS的,所以我就不进行样式布局了。
新建小姐姐组件
现在 SRC
的目录下面,新建一个文件 Xiaojiejie.js
文件,然后写一个基本的HTML结构。代码如下:
import React,{Component} from 'react' class Xiaojiejie extends Component{ render(){ return ( <div> <div><input /> <button> 增加服务 </button></div> <ul> <li>头部按摩</li> <li>精油推背</li> </ul> </div> ) } } export default Xiaojiejie 复制代码
这个文件现在还没有什么功能,只是写完了一个小组件。然后我们把入口文件的 <App />
组件换成 Xiajiejie
组件。
组件外层包裹原则
这是一个很重要的原则,比如上面的代码,我们去掉最外层的 <Div>
,就回报错,因为React要求必须在一个组件的最外层进行包裹。
错误代码(因为外边少了最外层的包裹):
import React,{Component} from 'react' class Xiaojiejie extends Component{ render(){ return ( <div><input /> <button> 增加服务 </button></div> <ul> <li>头部按摩</li> <li>精油推背</li> </ul> ) } } export default Xiaojiejie 复制代码
所以我们在写一个组件的时候,组件的最外层都需要有一个包裹。
Fragment标签讲解
加上最外层的DIV,组件就是完全正常的,但是你的布局就偏不需要这个最外层的标签怎么办?比如我们在作 Flex
布局的时候,外层还真的不能有包裹元素。这种矛盾其实React16已经有所考虑了,为我们准备了 <Fragment>
标签。
要想使用 <Fragment>
,需要先进行引入。
import React,{Component,Fragment } from 'react' 复制代码
然后把最外层的 <div>
标签,换成 <Fragment>
标签,代码如下。
import React,{Component,Fragment } from 'react' class Xiaojiejie extends Component{ render(){ return ( <Fragment> <div><input /> <button> 增加服务 </button></div> <ul> <li>头部按摩</li> <li>精油推背</li> </ul> </Fragment> ) } } export default Xiaojiejie 复制代码
这时候你再去浏览器的 Elements
中查看,就回发现已经没有外层的包裹了。
**总结:**下节课我们要实现增加服务项,期待下一集和技术胖一起开车吧。
第08节:React实例-宝剑磨的好,理论不能少
这节课我们主要了解一下React中的响应式设计原理和数据的绑定方法,俗话说的好:"宝剑磨的好,理论不能少"。这节课我们不仅要编写效果,还要讲理论,这节课很重要,因为这涉及 React
中的设计思想和你以后的编程思路。
响应式设计和数据的绑定
React
不建议你直接操作 DOM
元素,而是要通过数据进行驱动,改变界面中的效果。React会根据数据的变化,自动的帮助你完成界面的改变。所以在写React代码时,你无需关注DOM相关的操作,只需要关注数据的操作就可以了(这也是React如此受欢迎的主要原因,大大加快了我们的开发速度)。
现在的需求是增加小姐姐的服务项,就需要先定义数据。数据定义在 Xiaojiejie
组件中的构造函数里 constructor
。
//js的构造函数,由于其他任何函数执行 constructor(props){ super(props) //调用父类的构造函数,固定写法 this.state={ inputValue:'' , // input中的值 list:[] //服务列表 } } 复制代码
在 React
中的数据绑定和 Vue
中几乎一样,也是采用 字面量
(我自己起的名字)的形式,就是使用 {}
来标注,其实这也算是js代码的一种声明。比如现在我们要把 inputValue
值绑定到 input
框中,只要写入下面的代码就可以了。其实说白了就是在JSX中使用js代码。
<input value={this.state.inputValue} /> 复制代码
现在需要看一下是不是可以实现绑定效果,所以把 inputValue
赋予一个'jspang',然后预览看一下效果。在这里我们并没有进行任何的 DOM
操作,但是界面已经发生了变化,这些都时 React
帮我们作的,它还会自动感知数据的变化。
绑定事件
这时候你到界面的文本框中去输入值,是没有任何变化的,这是因为我们强制绑定了 inputValue
的值。如果要想改变,需要绑定 响应事件 ,改变 inputValue
的值。比如绑定一个改变事件,这个事件执行 inputChange()
(当然这个方法还没有)方法。
<input value={this.state.inputValue} onChange={this.inputChange} /> 复制代码
现在还没有 inputChange()
这个方法,在 render()
方法的下面建立一个 inputChange()
方法,代码如下:
inputChange(e){ console.log(e); } 复制代码
这时候会发现响应事件可以使用了,但是如何获得我们输入的值那,程序中输入下面的代码。
inputChange(e){ console.log(e.target.value); } 复制代码
这时候控制台是可以打印出输入的值的,视频中会有演示。看到获得了输入的值,想当然的认为直接改变 inputValue
的值就可以了(错的).
inputChange(e){ console.log(e.target.value); this.state.inputValue=e.target.value; } 复制代码
写完后再进行预览,会发现程序直接报错了(加项服务还真的有点难度哦,大宝剑不好作的...........)。
其实我们范了两个错误:
- 一个是
this
指向不对,你需要重新用bind
设置一下指向(ES6的语法)。 - 另一个是
React
中改变值需要使用this.setState
方法。
第一个错误很好解决,直接再 JSX
部分,利用 bind
进行绑定就好。
<input value={this.state.inputValue} onChange={this.inputChange.bind(this)} /> 复制代码
这步做完,我们还需要加入 setState
方法,改变值。代码如下:
inputChange(e){ // console.log(e.target.value); // this.state.inputValue=e.target.value; this.setState({ inputValue:e.target.value }) } 复制代码
现在测试一下,输入框可以改变值了,其实这节课很重要,里边设计了 React
的重要思想,建议这节课可以反复多看两遍,虽然不难,但是这是一个最基本的思想的转变。下节课可要真的增加服务项目了。
第09节:React实例-老板我要加个钟
有了上节课的基础,这节课终于可以添加服务,为所欲为了,随意增加你想要的服务了。这节课我们就来增加一个躺式采耳服务,体验一把帝王级待遇。
让列表数据化
现在的列表还是写死的两个 <li>
标签,那要变成动态显示的,就需要把这个列表先进行数据化,然后再用 javascript
代码,循环在页面上。
我们先给上节课的list数组增加两个数组元素,代码如下:
constructor(props){ super(props) //调用父类的构造函数,固定写法 this.state={ inputValue:'jspang' , // input中的值 //----------主要 代码--------start list:['基础按摩','精油推背'] //----------主要 代码--------end } } 复制代码
有了数据后,可以在 JSX
部分进行循环输出,代码如下:
render(){ return ( <Fragment> <div> <input value={this.state.inputValue} onChange={this.inputChange.bind(this)} /> <button> 增加服务 </button> </div> <ul> { this.state.list.map((item,index)=>{ return <li>{item}</li> }) } </ul> </Fragment> ) } 复制代码
完成上面的步骤,数据就不再是固定的了,而是动态管理的,也为我们接下来的添加打下了基础,剩下的步骤也显得很简单了。
增加服务选项
要增加服务选项,我们需要再增加按钮上先绑定一个方法 this.addList
(这个方法目前还没有,需要我们接下来建立).
<button onClick={this.addList.bind(this)}> 增加服务 </button> 复制代码
接下来就是把 this.addList
方法,代码如下:
//增加服务的按钮响应方法 addList(){ this.setState({ list:[...this.state.list,this.state.inputValue] }) } 复制代码
这里需要说的市 ...
这个是ES6的新语法,叫做扩展运算符。意思就是把list数组进行了分解,形成了新的数组,然后再进行组合。这种写法更简单和直观,所以推荐这种写法。
写完上面的代码,应该就可以实现增加项目了,你可以试着增加一下自己喜欢的服务进去,比如"中药泡脚"........
解决key值错误
高兴的同时其实是有一些隐患的,打开浏览器的控制台 F12
,可以清楚的看到报错了。这个错误的大概意思就是缺少 key值
。就是在用map循环时,需要设置一个不同的值,这个时React的要求。我们可以暂时用 index+item
的形式来实现。
<ul> { this.state.list.map((item,index)=>{ return <li key={index+item}>{item}</li> }) } </ul> 复制代码
这样就解决了这个隐患,现在就可以舒服的享受帝王级的服务了。
第10节:React实例-宝剑虽然好 老腰受不了
添加服务虽然很美妙,但是有时候也需要有些节制。这节课就学习如何删除一个服务选项。需求是这样的,当点击已经有的选项后,我们就进行删除。如果使用原生的js来写,这是非常麻烦的,但是有了 React
后就变的简单了。
数组下标的传递
如果要删除一个东西,就要得到数组里的一个编号,这里指下标。传递下标就要有事件产生,先来绑定一个双击事件.代码如下:
<ul> { this.state.list.map((item,index)=>{ return ( <li key={index+item} onClick={this.deleteItem.bind(this,index)} > {item} </li> ) }) } </ul> 复制代码
为了看着更清晰,我们在 return
部分加了 ()
这要就可以换行编写 JSX
代码了.在 onClick
我们绑定了 deleteItem
方法.
编写 deleteItem
方法
绑定做好了,现在需要把 deleteItem
,在代码的最下方,加入下面的代码.方法接受一个参数 index
.
//删除单项服务 deleteItem(index){ console.log(index) } 复制代码
这时候可以预览一下啊,已经在方法里获取到了下标.
正式删除数据
获得了数据下标后,删除数据就变的容易起来.先声明一个局部变量,然后利用传递过来的下标,删除数组中的值.删除后用 setState
更新数据就可以了.
//删除单项服务 deleteItem(index){ let list = this.state.list list.splice(index,1) this.setState({ list:list }) } 复制代码
其实这里边是有一个坑的,有的小伙伴肯定会认为下面的代码也是正确的.
//删除单项服务 deleteItem(index){ this.state.list.splice(index,1) this.setState({ list:this.state.list }) } 复制代码
记住React是禁止直接操作state的,虽然上面的方法也管用,但是在后期的性能优化上会有很多麻烦,所以一定不要这样操作.这也算是我 React
初期踩的比较深的一个坑,希望小伙伴们可以跳坑.
第11节:React进阶-JSX防踩坑的几个地方
上节课作完“大宝剑”菜单后,如果你跟着我做出来了,说明你的 React
已经入门了。也是一个好的开始,接下来的路虽然还很长,但会平坦的多。这节课就讲一下 JSX
语法中需要注意的几个小坑。
JSX代码注释
JSX
中的代码注释是非常有讲究的,这个书上介绍的也非常少,所以在这里讲一下,因为技术胖在初学 React
在这里踩过坑。
我第一次写 JSX
注释,是直接这样写的,当然这样写是完全不对的。
<Fragment> //第一次写注释,这个是错误的 <div> <input value={this.state.inputValue} onChange={this.inputChange.bind(this)} /> <button onClick={this.addList.bind(this)}> 增加服务 </button> </div> 复制代码
那写 JSX
的注释,可以有下面两种写法:
<Fragment> {/* 正确注释的写法 */} <div> <input value={this.state.inputValue} onChange={this.inputChange.bind(this)} /> <button onClick={this.addList.bind(this)}> 增加服务 </button> </div> 复制代码
如果你记不住,有个简单的方法,就是用 VSCode
的快捷键,直接按 Ctrl+/
,就会自动生成正确的注释了。
你可以把这个理解为,在jsx中写javascript代码。所以外出我们套入了 {}
,然后里边就是一个多行的javascript注释。如果你要使用单行祝注释 //
,你需要把代码写成下面这样。
<Fragment> { //正确注释的写法 } <div> <input value={this.state.inputValue} onChange={this.inputChange.bind(this)} /> <button onClick={this.addList.bind(this)}> 增加服务 </button> </div> 复制代码
也就是你要进行换行,所以个人认为这种方法不太优雅,所以推荐第一种注释方法。
JSX中的class陷阱
比如要给朴素单纯的界面,加入黄色成分,让我们的文本框又粗又黄。我们先来错误演示。
第一步:先写一个CSS样式文件,在 src
目录下,新建一个 style.css
的样式文件。
.input {border:3px solid #ae7000} 复制代码
第二步:在 Xiaojiejie.js
里引入,先用 import
进行引入,能用import引入,都是webpack的功劳。
import './style.css' 复制代码
第三部:给 JSX
加入`class,注意下面的代码是错误的。
<input class="input" value={this.state.inputValue} onChange={this.inputChange.bind(this)} /> 复制代码
虽然现在页面是可以正常显示结果的,但是你代开浏览器控制台会发现 Warning
警告。
index.js:1437 Warning: Invalid DOM property `class`. Did you mean `className`? in input (at Xiaojiejie.js:19) in div (at Xiaojiejie.js:18) in Xiaojiejie (at src/index.js:5) 复制代码
意思就是要把 class
换成 className
,它是防止和 js
中的 class
类名 冲突,所以要求换掉。这也算是一个小坑吧。
JSX中的 html
解析问题
如果想在文本框里输入一个 <h1>
标签,并进行渲染。默认是不会生效的,只会把 <h1>
标签打印到页面上,这并不是我想要的。如果工作中有这种需求,可以使用 dangerouslySetInnerHTML
属性解决。具体代码如下:
<ul> { this.state.list.map((item,index)=>{ return ( <li key={index+item} onClick={this.deleteItem.bind(this,index)} dangerouslySetInnerHTML={{__html:item}} > </li> ) }) } </ul> 复制代码
上面的代码就可以实现 html
格式的输出。
JSX中 <label>
标签的坑
JSX中 <label>
的坑,也算是比较大的一个坑,label是 html
中的一个辅助标签,也是非常有用的一个标签。
先看下面的代码,我们在文本框前面加入一个 <label>
。
<div> <label>加入服务:</label> <input className="input" value={this.state.inputValue} onChange={this.inputChange.bind(this)} /> <button onClick={this.addList.bind(this)}> 增加服务 </button> </div> 复制代码
这时候想点击“加入服务”直接可以激活文本框,方便输入。按照 html
的原思想,是直接加ID就可以了。代码如下:
<div> <label for="jspang">加入服务:</label> <input id="jspang" className="input" value={this.state.inputValue} onChange={this.inputChange.bind(this)} /> <button onClick={this.addList.bind(this)}> 增加服务 </button> </div> 复制代码
这时候你浏览效果虽然可以正常,但 console
里还是有红色警告提示的。大概意思是不能使用 for
.它容易和javascript里的for循环混淆,会提示你使用 htmlfor
。
<div> <label htmlFor="jspang">加入服务:</label> <input id="jspang" className="input" value={this.state.inputValue} onChange={this.inputChange.bind(this)} /> <button onClick={this.addList.bind(this)}> 增加服务 </button> </div> 复制代码
这时候代码就正确了,可以实现点击 <label>
后,激活 <input>
标签了。
这节算是我总结的一些 JSX
中的坑吧,总结出来,希望小伙伴们少踩这些坑,能快速上手 React
。
第12节:React进阶-Simple React Snippets
这节课很短,但是我觉的有必要单独拿出一节来讲讲。在工作中你经常会看到程序老司机写代码是非常快的,甚至让你烟花缭乱,那他们真的是单身那么多年,练就了超级快手吗?当然不是,只是他们使用了快速生成插件,这节课我就向大家介绍一个 vscode
中的 Simple React Snippets
,有了这个插件,稍加练习,你也可以像老司机一样,拥有加藤鹰的圣手(如果不懂请自行搜索吧)。
安装 Simple React Snippets
打开 VSCode
的插件查单,然后在输入框中输入 Simple React Snippets
,然后点击进行安装就可以了。
### 快速进行引入 import
直接在 vscode
中输入 imrc
,就会快速生成最常用的import代码。
import React, { Component } from 'react'; 复制代码
快速生成class
在作组件的时候,都需要写一个固定的基本格式,这时候你就可以使用快捷键 cc
.插件就会快速帮我们生成如下代码:
class extends Component { state = { } render() { return ( ); } } export default ; 复制代码
还有很多快捷键,我就没必要再这里唠叨了,如果你需要理解,打开插件的说明文件看一下就可以了。这个插件建议小伙伴们要熟练掌握,因为在老板眼里,代码编写速度的快慢直接跟我们的薪资有关,就是没什么关系。我们自己把时间剩下,去看小姐姐跳支舞不好吗?
第13节:React进阶-组件的拆分
现在的小姐姐服务菜单已经完美的制作好了,但是这从头到尾我们只用了一个组件,但是在实际工作中肯定是团队开发,我们会把一个大功能分成不同的组件。比如把文本框和按钮单独一个组件,把下面的服务列表单独一个组件,这涉及了一个组件拆分的能力和知识。这节课就把小姐姐服务菜单进行一个拆分。
新建服务菜单组件
在 src
目录下,新建一个文件,这里就叫做 XiaojiejieItem.js
,然后先把最基础的结构写好(这里最好练习一下上节课学习的快捷键)。
import React, { Component } from 'react'; //imrc class XiaojiejieItem extends Component { //cc render() { return ( <div>小姐姐</div> ); } } export default XiaojiejieItem; 复制代码
写好这些代码后,就可以到以前写的 Xiaojiejie.js
文件中用import进行引入,代码如下:
import XiaojijieItem from './XiaojiejiItem' 复制代码
### 修改 Xiaojiejie
组件
已经引入了新写的组件,这时候原来的代码要如何修改才能把新组件加入?
把原来的代码注释掉,当然你也可以删除掉,我这里就注释掉了,注释方法如下:
{/* <li key={index+item} onClick={this.deleteItem.bind(this,index)} dangerouslySetInnerHTML={{__html:item}} > </li> */ } 复制代码
然后在最外层加入包裹元素 <div>
,为的是防止两个以上的标签,产生错误信息。
最后直接写入 Xiaojiejie
标签就可以了.
<XiaojiejieItem /> 复制代码
为了方便你练习,给出全部代码:
import React,{Component,Fragment } from 'react' import './style.css' import XiaojiejieItem from './XiaojiejieItem' class Xiaojiejie extends Component{ //js的构造函数,由于其他任何函数执行 constructor(props){ super(props) //调用父类的构造函数,固定写法 this.state={ inputValue:'' , // input中的值 list:['基础按摩','精油推背'] //服务列表 } } render(){ return ( <Fragment> {/* 正确注释的写法 */} <div> <label htmlFor="jspang">加入服务:</label> <input id="jspang" className="input" value={this.state.inputValue} onChange={this.inputChange.bind(this)} /> <button onClick={this.addList.bind(this)}> 增加服务 </button> </div> <ul> { this.state.list.map((item,index)=>{ return ( //----------------关键修改代码----start <div> <XiaojiejieItem /> </div> //----------------关键修改代码----end ) }) } </ul> </Fragment> ) } inputChange(e){ // console.log(e.target.value); // this.state.inputValue=e.target.value; this.setState({ inputValue:e.target.value }) } //增加服务的按钮响应方法 addList(){ this.setState({ list:[...this.state.list,this.state.inputValue], inputValue:'' }) } //删除单项服务 deleteItem(index){ let list = this.state.list list.splice(index,1) this.setState({ list:list }) } } export default Xiaojiejie 复制代码
这时候可以预览一下效果,虽然现在已经把组件进行了拆分,但是还全是显示的小姐姐,还没有实现传值,下节课我们主要实现一下React组件之间的传值(父组件向子组件传递数据)。
第14节:React进阶-父子组件的传值
通过上节课的学习,已经把"小姐姐"组件做了一个基本的拆分,但是还不能实现随着输入,显示出输入的内容。这里涉及的是父组件向子组件传值。然后点击删除,就相当于子组件向父组件传值。这节课就主要学习一下父子组件传值的一些技巧。
父组件向子组件传值
这里只介绍最实用的,最快速的上手方法。就是使用组件属性的形式父组件给子组件传值。比如:我们在 <XiaojiejieItem>
组件中加入 content
属性,然后给属性传递 {item}
,这样就完成了父组件向子组件传值。
<XiaojiejieItem content={item} /> 复制代码
现在值已经顺利的传递了过去,这时候可以通过 this.props.xxx
的形式进行接受,比如传递过来的值,可以用如下代码进行接收。
import React, { Component } from 'react'; //imrc class XiaojiejieItem extends Component { //cc render() { return ( <div>{this.props.content}</div> ); } } export default XiaojiejieItem; 复制代码
修改完小姐姐子项的组件后,可以打开浏览器进行预览了。试着添加几个新的选项试一下,比如躺式采耳.....。
玩笑归玩笑,学到这里你要记住一点: 父组件向子组件传递内容,靠属性的形式传递。
子组件向父组件传递数据
现在要作这样一个功能:点击组件中的菜单项后,删除改菜单项。在前边的课程中已经学习了这个知识,知识现在组件拆分了,就涉及了一个字组件向父组件传递数据的知识需要掌握。
先来绑定点击事件,这时候当然是要在 XiaojiejieItem
组件中绑定了,代码如下:
import React, { Component } from 'react'; //imrc class XiaojiejieItem extends Component { //cc render() { return ( <div onClick={this.handleClick}>{this.props.content}</div> ); } handleClick(){ console.log('撩拨了小姐姐') } } export default XiaojiejieItem; 复制代码
这时候进行预览,打开F12,再点击服务菜单项,就会再 console
里显示出"撩拨了小姐姐"的字样。但是 console
里还有一个 warning
警告,这个警告我们见过,就是要求循环时必须设置key值。
修改 XiaoJieJie
组件的 render
代码如下:
<ul> { this.state.list.map((item,index)=>{ return ( <XiaojiejieItem key={index+item} content={item} /> ) }) } </ul> 复制代码
绑定成功后,现在就要通过操作子组件删除父组件里的数据了。但是React有明确规定,子组件时不能操作父组件里的数据的,所以需要借助一个父组件的方法,来修改父组件的内容。其实在以前已经写了一个删除方法 deleteItem
,现在要作的就是子组件调用这个方法。
//删除单项服务 deleteItem(index){ let list = this.state.list list.splice(index,1) this.setState({ list:list }) } 复制代码
获取数组索引下标
那现在问题来了,要删除就要知道索引值,还是需要通过父组件传递给子组件.这里还是通过 props
属性的形式进行传递。
<ul> { this.state.list.map((item,index)=>{ return ( <XiaojiejieItem key={index+item} content={item} index={index} /> ) }) } </ul> 复制代码
然后修改 XiaojiejieItem
组件,在 handleClick
方法里,写入下面代码:
handleClick(){ console.log(this.props.index) } 复制代码
这时候预览一下,你会发现点击后报错,错误还是我们的老朋友,没有 bind(this)
。那可以用以前的老方法绑定this.
return ( <div onClick={this.handleClick.bind(this)}> {this.props.content} </div> ); 复制代码
这样是可以决解的,但是肯定会有小伙伴说,我看别人不是这样写的,而是在构造函数里绑定的。(有言曰:构造函数中绑定性能会高一些,特别是在高级组件开发中,会有很大的作用)
constructor
绑定this方法。
import React, { Component } from 'react'; //imrc class XiaojiejieItem extends Component { //cc //--------------主要代码--------start constructor(props){ super(props) this.handleClick=this.handleClick.bind(this) } //--------------主要代码--------end render() { return ( <div onClick={this.handleClick}> {this.props.content} </div> ); } handleClick(){ console.log(this.props.index) } } export default XiaojiejieItem; 复制代码
子组件调用父组件方法
如果子组件要调用父组件方法,其实和传递数据差不多,只要在组件调用时,把方法传递给子组件就可以了,记得这里也要进行 this
的绑定,如果不绑定子组件是没办法找到这个父组件的方法的。
<ul> { this.state.list.map((item,index)=>{ return ( <XiaojiejieItem key={index+item} content={item} index={index} //关键代码-------------------start deleteItem={this.deleteItem.bind(this)} //关键代码-------------------end /> ) }) } </ul> 复制代码
传递后,在 XiaojiejieItem
组件里直接hi用就可以了,代码如下:
handleClick(){ this.props.deleteItem(this.props.index) } 复制代码
到此为止,就算是实现了子组件向父组件传值。特别提醒:这节课是React体系中非常重要的一节课,小伙伴们可以多听几遍,并进行练习。因为真正的React开发工作,每天写的就是各种组件,传值是组件之间产生联系的必要一环,无法跳跃。所以一定要学好。
第15节:React进阶-单项数据流和其他
这节课我们讲一些理论性的东西,比如:React单项数据流、React同其他框架共同工作和函数式编程的一些概念,这节课可能会稍显无聊,因为都是理论的东西,但是这些知识无论是在面试中,还是在工作中都会经常遇到,所以也是跳不过去的一节课。
单项数据流
React的特性中有一个概念叫做“单项数据流”,可能刚刚接触React的小伙伴不太明白这个概念,还是拿出《小姐姐服务菜单》的Demo,来给大家讲解。比如我们在父组件中可以直接把 this.state.list
传递过来。例如下面代码:
<ul> { this.state.list.map((item,index)=>{ return ( <XiaojiejieItem key={index+item} content={item} index={index} list={this.state.list} deleteItem={this.deleteItem.bind(this)} /> ) }) } </ul> 复制代码
其实这样传是没有问题的,问题是你只能使用这个值,而不能修改这个值,如果你修改了,比如我们把代码写成这样:
handleClick(){ //关键代码——---------start this.props.list=[] //关键代码-----------end this.props.deleteItem(this.props.index) } 复制代码
就会报下面的错误;
TypeError: Cannot assign to read only property 'list' of object '#<Object>' 复制代码
意思就是 list
是只读的,单项数据流。那如果要改变这里边的值怎么办?其实上节课已经讲过了,就是通过传递父组件的方法。
和其他框架配合使用
有小伙伴问我, React
和 jquery
能一起使用吗?
答案:是可以的,React其实可以模块化和组件化开发。看 /public/index.html
文件,代码如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="theme-color" content="#000000" /> <link rel="manifest" href="%PUBLIC_URL%/manifest.json" /> <title>React App</title> </head> <body> <noscript>You need to enable JavaScript to run this app.</noscript> <!--关键代码start--> <div id="root"></div> <!--关键代码end--> </body> </html> 复制代码
其实React只对这一个 <div>
,外边的其他DOM并不受任何影响,比如我们在它的下方再写一个 <div>
,然后查看效果。
<div id="root"></div> <div style="color:red">今天过的好开心,服务很满意!</div> 复制代码
你可以在其他的div里加入任何内容,但是这种情况很少,我也不建议这么使用。希望小伙伴们还是统一技术栈。
函数式编程
在面试React时,经常会问道的一个问题是:函数式编程的好处是什么?
- 函数式编程让我们的代码更清晰,每个功能都是一个函数。
- 函数式编程为我们的代码测试代理了极大的方便,更容易实现前端自动化测试。
React框架也是函数式编程,所以说优势在大型多人开发的项目中会更加明显,让配合和交流都得心应手。
总结:这节课虽然都是些理论知识,这些知识在面试中经常被问到,所以也是必须掌握的内容。
第16节:React高级-调试工具的安装及使用
已经可以简单的写一些React代码了,在视频中,我也是经常使用 console.log
这种很二的形式来调试程序。其实React在浏览器端是有一个调试工具的,这就是 React developer tools
,这个是React人必下的一个调试工具。这节课就主要学习一下 React developer tools
的下载和简单使用。
下载React developer tools
这个需要在 chrome浏览器
里进行,并且需要科学上网(这东西我不能在这里教,所以自行百度吧)。
-
点击浏览器地址栏最右边的
...
,然后选择更多工具
,然后选择扩展程序
。 -
点击
打开chrome网上应用店
,直接在搜索框里搜索React
,出现的第一个就是。 -
点击
添加至Chrome
,然后就是等待了..........
这段内容推荐看视频吧,其实并不复杂,但是都是需要上图的,我又懒得作图。
React developer tools的三种状态
React developer tools
有三种颜色,三种颜色代表三种状态:
- 灰色: 这种就是不可以使用,说明页面不是又React编写的。
- 黑色: 说明页面是用React编写的,并且处于生成环境当中。
- 红色: 说明页面是用React编写的,并且处于调试环境当中。
React developer tools使用
打开浏览器,然后按 F12
,打开开发者工具,然后在面板的最后一个,你会返现一个 React
,这个就是安装的插件了。
在这里你可以清晰的看到React的结构,让自己写的代码更加清晰,你还可以看到组间距的数据传递,再也不用写 console.log
来测试程序了。
总结: 这节课我们学习了React调试工具的安装和使用,在工作中一个前端的调试都是在这里进行的,所以拿出单独的一节课来讲一下。
第17节:React高级-PropTypes校验传递值
在父组件向子组件传递数据时,使用了属性的方式,也就是props,但“小姐姐服务菜单”的案例并没有任何的限制。这在工作中时完全不允许的,因为大型项目,如果你不校验,后期会变的异常混乱,业务逻辑也没办法保证。
PropTypes的简单应用
我们在 Xiaojiejie.js
组件里传递了4个值,有字符串,有数字,有方法,这些都是可以使用 PropTypes
限制的。在使用需要先引入 PropTypes
。
import PropTypes from 'prop-types' 复制代码
引入后,就可以在组件的下方进行引用了,需要注意的是子组件的最下面(不是类里边),写入下面的代码:
XiaojiejieItem.propTypes={ content:PropTypes.string, deleteItem:PropTypes.func, index:PropTypes.number } 复制代码
具体意思,我会在视频中进行讲解,请观看视频。为了防止你的为止写错,我这里给出这个 XiaojiejieItem.JS
文件的代码。
import React, { Component } from 'react'; //imrc import PropTypes from 'prop-types' class XiaojiejieItem extends Component { //cc constructor(props){ super(props) this.handleClick=this.handleClick.bind(this) } render() { return ( <div onClick={this.handleClick}> {this.props.content} </div> ); } handleClick(){ this.props.deleteItem(this.props.index) } } //--------------主要代码--------start XiaojiejieItem.propTypes={ content:PropTypes.string, deleteItem:PropTypes.func, index:PropTypes.number } //--------------主要代码--------end export default XiaojiejieItem; 复制代码
这时候你在浏览器中查看效果,是什么都看不出来的,你需要修改一个错误的校验。比如我们把index改为必须是字符串。
index:PorpTypes.string 复制代码
这时候浏览器的 console
里就会报错了,报错信息如下:
Warning: Failed prop type: Invalid prop `index` of type `number` supplied to `XiaojiejieItem`, expected `string`. in XiaojiejieItem (at Xiaojiejie.js:28) in Xiaojiejie (at src/index.js:5) 复制代码
意思就是要求传递字符串,而我们却传递了数字过去,所以给了警告。
### 必传值的校验
比如现在我们加入一个 avname
的属性,并放入 JSX
中,就算不传递这个值也不会报错的。代码如下:
render() { return ( <div onClick={this.handleClick}> {this.props.avname}为你做- {this.props.content} </div> ); } 复制代码
这时候代码是不会报错的,我们传不传无所谓。比如我们现在传一个属性过来。
<ul> { this.state.list.map((item,index)=>{ return ( <XiaojiejieItem key={index+item} content={item} index={index} avname='波多野结衣' deleteItem={this.deleteItem.bind(this)} /> ) }) } </ul> 复制代码
这时候页面显示正常了,但是怎样避免必须传递avname这个属性值?如果不传递就报错,这就需要使用 isRequired
关键字了,它表示必须进行传递,如果不传递就报错。
avname:PropTypes.string.isRequired 复制代码
### 使用默认值 defaultProps
有些人是非常腼腆的,他是不好意思选择的,所以有时候是需要有一个默认的人为她服务的。 defalutProps
就可以实现默认值的功能,比如现在把 avname
的默认值设置成"松岛枫" ,然后把 avname
的属性删除掉。
XiaojiejieItem.defaultProps = { avname:'松岛枫' } 复制代码
其实检测的类型非常多,你最好去官方文档看一下,能得到比较全面的了解。下面的课程有用到特殊的类型,还会继续给小伙伴们讲解。
第18节:React高级-ref的使用方法
在编写组件中的方法时,经常会遇到语义化很模糊的代码,这对于团队开发是一个很大的问题。因为review代码或者合作时都会影响开发效率。或者到这核心成员离开,项目倒闭的严重影响。所以我们必须重视react代码当中的语义化。ref是个不错的工具,快来学习一下吧。
代替原来的 e.target.value
以前的案例中,我们写了下面的代码,使用了 e.target
,这并不直观,也不好看。这种情况我们可以使用 ref
来进行解决。
inputChange(e){ this.setState({ inputValue:e.target.value }) } 复制代码
如果要使用 ref
来进行,需要现在 JSX
中进行绑定, 绑定时最好使用ES6语法中的箭头函数,这样可以简洁明了的绑定DOM元素。
<input id="jspang" className="input" value={this.state.inputValue} onChange={this.inputChange.bind(this)} //关键代码——----------start ref={(input)=>{this.input=input}} //关键代码------------end /> 复制代码
绑定后可以把上边的类改写成如下代码:
inputChange(){ this.setState({ inputValue:this.input.value }) } 复制代码
这就使我们的代码变得语义化和优雅的多。但是就我个人的经验来讲,我是不建议用 ref
这样操作的,因为 React
的是数据驱动的,所以用ref会出现各种问题。
ref
使用中的坑
比如现在我们要用ref绑定取得要服务的数量,可以先用 ref
进行绑定。
<ul ref={(ul)=>{this.ul=ul}}> { this.state.list.map((item,index)=>{ return ( <XiaojiejieItem key={index+item} content={item} index={index} deleteItem={this.deleteItem.bind(this)} /> ) }) } </ul> 复制代码
绑定后可以在 addList()
方法中,获取当前 <div>
的值.
addList(){ this.setState({ list:[...this.state.list,this.state.inputValue], inputValue:'' }) //关键代码--------------start console.log(this.ul.querySelectorAll('div').length) //关键代码--------------end } 复制代码
这时候你打开控制台,点击添加服务按钮,你会返现数量怎么少一个?(就是这个坑),其实这个坑是因为React中更多 setState
是一个异步函数所造成的。也就是这个 setState
,代码执行是有一个时间的,如果你真的想了解清楚,你需要对什么是虚拟DOM有一个了解。简单的说,就是因为是异步,还没等虚拟Dom渲染,我们的 console.log
就已经执行了。
那这个代码怎么编写才会完全正常那,其实 setState
方法提供了一个回调函数,也就是它的第二个函数。下面这样写就可以实现我们想要的方法了。
addList(){ this.setState({ list:[...this.state.list,this.state.inputValue], inputValue:'' //关键代码--------------start },()=>{ console.log(this.ul.querySelectorAll('div').length) }) //关键代码--------------end } 复制代码
现在到浏览器中查看代码,就完全正常了。这节课主要学习了 ref
的用法和 ref
中的坑。学完后练习一下吧,代码这东西,不练习你是学不会的。
第19节:React高级-生命周期讲解-1
React
的生命周期是非常重要的知识点,所以关于React声明周期的课程可以多看几遍,我也会尽量的把React的生命周期讲的细致。生命周期的课程我分成三节来讲,这样更容易让你理解。
React生命周期图
这张图看起来有点复杂,但是小伙伴们不要有恐慌心里,我会抽丝剥茧,给你详细讲解。
通过这张图你可以看到React声明周期的四个大阶段:
Initialization Mounting Updation Unmounting
什么是生命周期函数
如果非要用一句话把生命周期函数说明白,我觉的可以用这句话来说明:
生命周期函数指在某一个时刻组件会自动调用执行的函数
举例:写的小姐姐的例子。里边的 render()
函数,就是一个生命周期函数,它在state发生改变时自动执行。这就是一个标准的自动执行函数。
-
constructor
不算生命周期函数。
constructor
我们叫构造函数,它是ES6的基本语法。虽然它和生命周期函数的性质一样,但不能认为是生命周期函数。
但是你要心里把它当成一个生命周期函数,我个人把它看成React的 Initialization
阶段,定义属性(props)和状态(state)。
Mounting阶段
Mounting阶段叫挂载阶段,伴随着整个虚拟DOM的生成,它里边有三个小的生命周期函数,分别是:
componentWillMount render componentDidMount
componentWillMount代码
componentWillMount(){ console.log('componentWillMount----组件将要挂载到页面的时刻') } 复制代码
componentDidMount代码
componentDidMount(){ console.log('componentDidMount----组件挂载完成的时刻执行') } 复制代码
render代码
render(){ console.log('render---组件挂载中.......') } 复制代码
这时候我们查看一下控制台,会为我们打出如下提示:
componentWillMount----组件将要挂载到页面的时刻执行 render----开始挂载渲染 componentDidMount----组件挂载完成的时刻执行 复制代码
这也是生命周期的顺序。有小伙伴会问我,这个函数书写有顺序吗?哪个在前?哪个在后?其实是没有顺序的,你可以随便改动他们的顺序。
注意的问题
componentWillMount
和 componentDidMount
这两个生命周期函数,只在页面刷新时执行一次,而 render
函数是只要有state和props变化就会执行,这个初学者一定要注意。
视频中会举例说明。
总结:这节课讲解了React的生命周期函数,先是简单了解了一下React生命周期函数的四大阶段,然后又详细学习了一下 Mounting
挂载阶段中的三个生命周期函数。下节课会学习 Updation
阶段的生命周期函数。
第20节:React高级-生命周期讲解-2
这节继续学习React生命周期中的 Updation
阶段,也就是组件发生改变的更新阶段,这是React生命周期中比较复杂的一部分,它有两个基本部分组成,一个是 props
属性改变,一个是 state
状态改变(这个在生命周期的图片中可以清楚的看到)。
shouldComponentUpdate函数
shouldComponentUpdate
函数会在组件更新之前,自动被执行。比如写入下面的代码:
shouldComponentUpdate(){ console.log('shouldComponentUpdate---组件发生改变前执行') } 复制代码
它要求返回一个布尔类型的结果,必须有返回值,这里就直接返回一个 true
了(真实开发中,这个是有大作用的)。
shouldComponentUpdate(){ console.log('shouldComponentUpdate---组件发生改变前执行') return true } 复制代码
现在就可以在控制台 console
里看到结果了,并且结果是每次文本框发生改变时都会随着改变。如果你返回了 false
,这组件就不会进行更新了。 简单点说,就是返回true,就同意组件更新;返回false,就反对组件更新。
componentWillUpdate函数
componentWillUpdate
在组件更新之前,但 shouldComponenUpdate
之后被执行。但是如果 shouldComponentUpdate
返回false,这个函数就不会被执行了。
//shouldComponentUpdate返回true才会被执行。 componentWillUpdate(){ console.log('componentWillUpdate---组件更新前,shouldComponentUpdate函数之后执行') } 复制代码
componentDidUpdate
componentDidUpdate
在组件更新之后执行,它是组件更新的最后一个环节。
componentDidUpdate(){ console.log('componentDidUpdate----组件更新之后执行') } 复制代码
为了方便我们看出结果,可以在每个函数前加上序号。最后我们可以看到控制台输出的结果如下:
1-shouldComponentUpdate---组件发生改变前执行 2-componentWillUpdate---组件更新前,shouldComponentUpdate函数之后执行 3-render----开始挂载渲染 4-componentDidUpdate----组件更新之后执行 复制代码
结果和我们写的顺序也是相对的,讲到这里,你一定对React的生命周期函数有了比较直观的了解了。
componentWillReceiveProps 函数
我们可以先在 Xiaojiejie.js
组件里写下这个函数,例如下面的代码。
componentWillReceiveProps(){ console.log('componentWillReceiveProps') } 复制代码
这时候会发现函数什么时候都不会被执行,因为 Xiaojiejie.js
算是一个顶层组件,它并没接收任何的 props
。可以把这个函数移动到 XiaojiejieItem.js
组件中。
凡是组件都有生命周期函数,所以子组件也是有的,并且子组件接收了 props
,这时候函数就可以被执行了。
componentWillReceiveProps(){ console.log('child - componentWillReceiveProps') } 复制代码
这个时候再预览,就会看到 componentWillReceiveProps
执行了。那现在可以总结一下它的执行时间了。
子组件接收到父组件传递过来的参数,父组件render函数重新被执行,这个生命周期就会被执行。
- 也就是说这个组件第一次存在于Dom中,函数是不会被执行的;
- 如果已经存在于Dom中,函数才会被执行。
这个生命周期算是比较复杂的一个生命周期,需要我们花点时间去消化。
这节课就把 updation
里的生命周期函数都讲过了,下节课会把剩下的一点 Unmounting
讲了,然后会讲一下生命周期的实际应用。
第21节:React高级-生命周期讲解-3
其实这节课算是一个小的补充,把最后一个React的生命周期函数讲一下,这个生命周期周期函数就是 componentWillUnmount
,它是在组件去除时执行。
componentWillUnmount函数
这个函数时组件从页面中删除的时候执行,比如在 XiaojiejieItem.js
,写入下面的代码:
//当组件从页面中删除的时候执行 componentWillUnmount(){ console.log('child - componentWillUnmount') } 复制代码
写完后,可以到浏览器终端中查看结果,当我们点击服务项,服务项被删除时,这个函数就被执行了。
总结:通过三节课的学习,我们已经把React的所有生命周期函数都讲完了,下节课会具体讲一下生命周期函数在实际开发中的应用。
第22节:React高级-生命周期改善程序性能
已经对 React
生命周期有了认识,那如何利用它提高组件的性能那?这节课我们会讲一个通过 shouldComponentUpdate
函数,改善React组件性能的例子。为了让这节课讲述的内容更加清晰,可以删除上几节课的生命周期函数。
小姐姐组件存在性能问题
是的,小姐姐组件已经写的很熟悉了,但是它有一个性能问题,我一直没告诉你,那就是子组件 XiaojiejieItem
频繁无用渲染 render
。如何能看出这个问题的那?
首先你要确认你安装了 React Developer Tools
如果你没有安装,可以到前边的课程学习一下安装。有了这个浏览器插件,就可以在控制台中找到React标签,然后在右边点开设置,选中 highlight Updates
。
这时候你在浏览器的文本框中输入一下内容,你可以清楚的看到子组件也发生了重新 render
的情况。
有很多 程序员 会忽略这样的性能损耗,认为没有什么大不了的,但是软件的卡顿是一点点产生的,所以必须要减少性能损耗。
可以在 XiaojiejieItem.js
的 render
函数里加入下面的代码,更直观的看到这个问题。
render() { console.log('child-render') return ( <div onClick={this.handleClick}> {this.props.avname}为你做- {this.props.content} </div> ); } 复制代码
利用 shouldComponentUpdate
解决
这个问题看似很小,但是当你页面很复杂时,足以影响用户体验,不要骗自己了。其实用 shouldComponentUpdate
函数就可以简单的解决调这个问题。
直接再 XiaojiejieItem.js
中加入下面的代码:
shouldComponentUpdate(){ return false; } 复制代码
这时候在浏览器中查看,问题已经没有了。但是这样做太暴力了,否定了所有的东西,那如果在真实项目中,需要改变值属性值,达到渲染就没办法了。所以我们可以更优雅一下,写出下面的代码。
shouldComponentUpdate有两个参数:
- nextProps:变化后的属性;
- nextState:变化后的状态;
shouldComponentUpdate(nextProps,nextState){ if(nextProps.content !== this.props.content){ return true }else{ return false } } 复制代码
现在的代码就优雅一些了,也不那么暴力了。这就算是完美解决了子组件的渲染性能问题,你写的代码质量也得到了提高。其实在面试React让写TODOList应用的,都是看这个来区分等级的,能写出来的,这算普通程序员;能写出来并作性能优化的,这算有经验的程序员。
第23节:React高级-axios数据请求
有了生命周期的知识,这节课学习远程数据请求的知识,小伙伴们肯定都知道, ajax
可以远程请求,但是这写起来太麻烦了,我们用程序的ajax请求框架 Axios
来实现。
安装Axios
Axios
的安装可以使用npm来进行安装,你可以直接在项目根目录下,输入下面的代码。
npm install -save axios 复制代码
输入 后就可以正在的开始安装了。
npm install -save 和 -save-dev分不清
-
npm install xxx
: 安装项目到项目目录下,不会将模块依赖写入devDependencies
或dependencies
。 -
npm install -g xxx
:-g
的意思是将模块安装到全局,具体安装到磁盘哪个位置,要看npm cinfig prefix
的位置 -
npm install -save xxx
:-save
的意思是将模块安装到项目目录下,并在package
文件的dependencies
节点写入依赖。 -
npm install -save-dev xxx
:-save-dev
的意思是将模块安装到项目目录下,并在package
文件的devDependencies
节点写入依赖。
作为一个前端,要清楚的知道 npm install
这四种用法,防止项目依赖错误,在别人下载你的代码没办法跑起来。
axios请求数据
安装好 axiso
之后,需要在使用ajax的地方先引入 axios,比如现在想在
Xiaojiejie.js 中使用
axios`,写入下面的代码进行引入:
import axios from 'axios' 复制代码
引入后,可以在 componentDidMount
生命周期函数里请求ajax,我也建议在 componentDidMount
函数里执行,因为在render里执行,会出现很多问题,比如一直循环渲染;在 componentWillMount
里执行,在使用RN时,又会有冲突。所以强烈建议在 componentDidMount
函数里作 ajax
请求。
componentDidMount(){ axios.post('https://web-api.juejin.im/v3/web/wbbr/bgeda') .then((res)=>{console.log('axios 获取数据成功:'+JSON.stringify(res)) }) .catch((error)=>{console.log('axios 获取数据失败'+error)}) } 复制代码
上面的代码是以掘金的一个接口为例,做了一次 ajax
请求。并且请求到了数据,给我们返回了。 总结:这节课学习了 Axios
的简单用法,并用最简单的方式,请求到了一个掘金网站的数据接口。ajax请求在你的项目中,会经常使用,也是我们读取和写入数据的一个桥梁,所以学习 React
的过程中,使用 Axios
作ajax请求非常重要,动手练习一下吧。
第24节:React高级-Axios请求EasyMock
上节课只是小试身手,用了一个掘金的临时接口,这个接口并不是自己写的,没准什么时候就不能使用了。在开发中都是前后端分离的,我们也需要自己模拟数据,通常把自己模拟数据这个过程就叫做 mock
,你可以用软件自己本地模拟数据,但是作为一个云注意者,我还是选择使用 Easy-mock
来模拟接口数据。
EasyMock新建一个接口
EasyMock网站:www.easy-mock.com/
然后你没注册需要注册一下,剩下的过程就看视频吧,因为这个都是些图形化的东西,我在视频中会详细讲解。
在创建接口时,写下如下代码:
{ "data": ['基础按摩', '躺式采耳', '中药泡脚'] } 复制代码
然后在上节课的Axios代码部分,把请求改为 get
,然后预览,到控制台查看结果。
componentDidMount(){ axios.get('改为你自己的接口URL') .then((res)=>{console.log('axios 获取数据成功:'+JSON.stringify(res)) }) .catch((error)=>{console.log('axios 获取数据失败'+error)}) } 复制代码
这时候你应该可以获得接口数据了,也说明我们的接口制作正常了,这就很类似我们项目中的真实接口了。
修改程序 变为动态接口
在客户端已经得到了远程数据,那剩下的就是 setState
一下就可以了,代码如下:
componentDidMount(){ axios.get('xxxx') .then((res)=>{ console.log('axios 获取数据成功:'+JSON.stringify(res)) this.setState({ list:res.data.data }) }) .catch((error)=>{console.log('axios 获取数据失败'+error)}) } 复制代码
那这时候再浏览React程序,也是完全可以使用的,不过已经不是以前写死的东西,而是使用远端接口数据。
总结:我们这两节课只是让你简单的学会React远程请求接口的方法,以后会用实战给大家讲解这部分知识,这里只要做到有个基本认识就可以了。
第25节:React高级-用CSS3实现react动画
前端的动画技术发展到现在,完全可以独立出一个岗位。我目前不属于动画岗,能力有限,也只是简单的给小伙伴们讲讲,做一些前端常用的效果。这节课先用我们最熟悉的CSS3在React中制作一个显示隐藏的动画特效,注意这是用CSS3实现的,其实React只做了业务逻辑。
新建一个Boss组件
其实这个组件你起什么名字都行,我也是临时想到的。
需要给“小姐姐服务菜单”增加一个Boss服务人物,点击一下按钮就会自动出现"Boss级人物-孙悟空",不要管什么恰当不恰当了,咱们是为了练习一下动画。在 src
文件夹下,新建一个 Boss.js
文件。然后用快速生成的方式生成基本结构:
在使用这些命令前,你要保证你安装了VSCode中的 Simple React Snippets
插件。
- 先输入
imrc
,然后回车,这是为了用import
引入React
和component
。 - 再输入
ccc
然后回车,生成最基本的带constructor
的代码结构。
就会生成下面的基本代码了(2秒钟完成下面的代码,这也是你工作中提高效率的关键):
import React, { Component } from 'react'; class Boss extends Component { constructor(props) { super(props); this.state = { } } render() { return ( ); } } export default Boss; 复制代码
然后我们先写一些JSX代码,让页面上有一段文字和一个按钮。代码如下:
import React, { Component } from 'react'; class Boss extends Component { constructor(props) { super(props); this.state = { } } render() { return ( <div> <div>BOSS级人物-孙悟空</div> <div><button>召唤Boss</button></div> </div> ); } } export default Boss; 复制代码
编写业务逻辑
目前组件没有任何业务逻辑,只有一个UI,这是没办法实现动画效果的。业务逻辑是点击按钮的时候可以改变字的'
constructor
里增加state值
isShow
,详情请看下面的代码。
this.state = { isShow:true } 复制代码
然后把“字”的'
className
,并用
isShow
进行控制。
<div className={this.state.isShow ? 'show' : 'hide'}>BOSS级人物-孙悟空</div> 复制代码
需要点击按钮时,有响应的事件,所以需要一个方法,我们编写一个 toToggole()
方法,代码如下:
toToggole(){ this.setState({ isShow:this.state.isShow ? false : true }) } 复制代码
意思就是当 isShow
为 true
时,我们赋值 false
;当 isShow
为 false时,我们赋值
true`.
有了方法后,可以给 <button>
加上 onClick
响应事件了,代码如下:
<div><button onClick={this.toToggole}>召唤Boss</button></div> 复制代码
写完这个事件,还是需要到 constructor
里绑定一下 this
。代码如下:
constructor(props) { super(props); this.state = { isShow:true } this.toToggole = this.toToggole.bind(this); } 复制代码
这样我们的基本业务逻辑就算写完了,可以把代码加入到 Xiaojiejie
组件中,看一下效果了。
加入CSS动画
在页面上看不出任何的效果,如果你打开浏览器控制台是可以看到每次点击按钮,class都会变化的。界面没变化,知识我们没有写CSS。现在可以在 style.css
里写样式,代码如下:
.show{ opacity: 1; transition:all 1.5s ease-in;} .hide{opacity: 0; transition:all 1.5s ease-in;} 复制代码
这样就用CSS3实现了React中动画,这知识最简单的实践动画,所以先不要吐槽,接下来几节课我们会继续讲解React中动画的知识。继续跟着技术胖一起学习吧。
第26节:React高级-CSS3的keyframes动画
用 transition
只能作一些最简单的动画,如果你想稍微复杂点, transition
就做不出来了。这时候就可以用CSS3中的关键帧动画 keyframes
。这节课就花几分钟学习一下keyframes,如果你CSS3动画不能分的知识很好,完全可以跳过这节课。
keyframes动画介绍
此属性与 animation
属性是密切相关的, keyframes
译成中文就是关键帧,我最早接触这个关键帧的概念是字flash中,现在Flash已经退出历史舞台了。他和 transition
比的优势是它可以更加细化的定义动画效果。比如我们设置上节课的按钮隐藏动画,不仅可以设置透明度,还可以设置颜色。
@keyframes hide-item{ 0% { opacity:1; color:yellow; } 50%{ opacity: 0.5 ; color:red; } 100%{ opacity:0; color: green; } } 复制代码
这就算是你的动画制作好了,但是动画还没有使用。
使用动画
使用动画的关键词是 animation
,然后后边跟上你的制作的动画名称,如下面这段代码。
.hide{ animation:hide-item 2s ease-in ; } 复制代码
这句的意思就是,使用 hide-item
动画,持续时间是2秒钟,然后缓动效果是由慢到快(开始的时候慢,之后快)。
但是你会发现,动画执行一遍后又恢复了原状,这个是因为没设置 forwards
属性,它是用来控制停止到最后一帧的。 我们把代码改写成下面的样子。
.hide{ animation:hide-item 2s ease-in forwards; } 复制代码
完整代码的实现
那 keyframes
的动画已经基本学会了,接下来就把所有的代码修改为 keyframes
的形式吧。所有代码如下:
.show{ animation:show-item 2s ease-in forwards; } .hide{ animation:hide-item 2s ease-in forwards; } @keyframes hide-item{ 0% { opacity:1; color:yellow; } 50%{ opacity: 0.5 ; color:red; } 100%{ opacity:0; color: green; } } @keyframes show-item{ 0% { opacity:0; color:yellow; } 50%{ opacity: 0.5 ; color:red; } 100%{ opacity:1; color: green; } } 复制代码
总结: keyframes
也是只能实现很简单的动画效果,一些复杂的动画最好还是使用别人造好的轮子,下节课继续学习 React
中的动画吧。
第27节:React高级-react-transition-group
React有着极好的开发生态,开发需要的任何基本需求都可以找到官方或大神造的轮子,动画这种必不可少的东西当然也不例外,React生态中有很多第三方的动画组件,你应该学习一下 react-transition-group
动画组件。目前我在工作中使用表现很好,可以满足日常动画开发需求。
推荐的最重要理由是:这个也是react官方提供的动画过渡库,有着完善的API文档(完善到我都不好意思再讲一遍)。
安装react-transition-group
使用它要先进行安装,这里使用 npm
的形式进行安装了,当然也可以使用 yarn
。
先用 VSCode
打开项目根目录,然后打开终端,输入下面的命令,进行安装:
npm install react-transition-group --save 复制代码
安装好后,你可以先去github上来看一下文档,他是有着三个核心库(或者叫组件)。
- Transition
- CSSTransition
- TransitionGroup
### 使用CSSTransition
其实这个库用起来根 ng-animate
差不多,先来看看如何使用 CSSTransition
。
先用 import
进行引入,代码如下:
import { CSSTransition } from 'react-transition-group' 复制代码
引入后便可以使用了,使用的方法就和使用自定义组件一样,直接写 <CSSTransition>
,而且不再需要管理 className
了,这部分由 CSSTransition
进行管理。修改上节课写的 Boss.js
文件里的 render
区域。
render() { return ( <div> <CSSTransition in={this.state.isShow} //用于判断是否出现的状态 timeout={2000} //动画持续时间 classNames="boss-text" //className值,防止重复 > <div>BOSS级人物-孙悟空</div> </CSSTransition> <div><button onClick={this.toToggole}>召唤Boss</button></div> </div> ); } 复制代码
需要注意的是 classNames
这个属性是由 s
的,如果你忘记写,会和原来的 ClassName
混淆出错,这个一定要注意。
我们把上节课的代码进行了改造,然后你就可以到CSS中改写 style
了。在修改样式之前,有那些类名。
- xxx-enter: 进入(入场)前的CSS样式;
- xxx-enter-active:进入动画直到完成时之前的CSS样式;
- xxx-enter-done:进入完成时的CSS样式;
- xxx-exit:退出(出场)前的CSS样式;
- xxx-exit-active:退出动画知道完成时之前的的CSS样式。
- xxx-exit-done:退出完成时的CSS样式。
知道了这些要设置的CSS,就可以删除原来写的CSS了,把下面的代码写上:
.input {border:3px solid #ae7000} .boss-text-enter{ opacity: 0; } .boss-text-enter-active{ opacity: 1; transition: opacity 2000ms; } .boss-text-enter-done{ opacity: 1; } .boss-text-exit{ opacity: 1; } .boss-text-exit-active{ opacity: 0; transition: opacity 2000ms; } .boss-text-exit-done{ opacity: 0; } 复制代码
这时候你的动画样式就正常了,你回发现我们再也不用自己管理className了,而是完全交给了 react-transition-group
来作。
unmountOnExit 属性
学到这里,会感觉这样写也没有简化多少,更没特殊的效果,技术胖你又玩我。
其实不是的,比如我们给 <CSSTransition>
加上 unmountOnExit
,加上这个的意思是在元素退场时,自动把DOM也删除,这是以前用CSS动画没办法做到的。
比如我们把代码写成这个样子:
render() { return ( <div> <CSSTransition in={this.state.isShow} //用于判断是否出现的状态 timeout={2000} //动画持续时间 classNames="boss-text" //className值,防止重复 unmountOnExit > <div>BOSS级人物-孙悟空</div> </CSSTransition> <div><button onClick={this.toToggole}>召唤Boss</button></div> </div> ); } 复制代码
总结:这几课简单的学习了一下React官方的 react-transition-group
动画库,也实现了一些动画效果。下节课继续学习动画库中的钩子函数和 transition-group
。
第28节:React高级-多DOM动画制作和编写
通过上一节的学习,只能控制一个DOM元素的动画,想控制多个动画 react-transition-group
这个动画库也是可以做到的。这节课就带你了解一下多DOM动画控制的方法。
使用 TransitionGroup
它就是负责多个DOM元素的动画的,我们还是拿小姐姐这个案例作例子,现在可以添加任何的服务项目,但是都是直接出现的,没有任何动画,现在就给它添加上动画。添加动画,先引入 transitionGrop
。
直接打开 /src/Xiaojiejie.js
的文件,然后在最顶部同时
import {CSSTransition , TransitionGroup} from 'react-transition-group' 复制代码
引入之后,就可以使用这个组件了,方法是在外层增加 <TransitionGroup>
标签。
<ul ref={(ul)=>{this.ul=ul}}> <TransitionGroup> { this.state.list.map((item,index)=>{ return ( <XiaojiejieItem key={index+item} content={item} index={index} deleteItem={this.deleteItem.bind(this)} /> ) }) } </TransitionGroup> </ul> 复制代码
这个需要放在循环的外边,这样才能形成一个组动画,但是只有这个 <TransitonGroup>
是不够的,你还是需要加入 <CSSTransition>
,来定义动画。
加入 <CSSTranstion>
标签
可以完全仿照上节课的经验,为 Xiaojiejie
组件,加上具体的动画设置,就可以实现多DOM元素的动画效果了。代码如下:
<ul ref={(ul)=>{this.ul=ul}}> <TransitionGroup> { this.state.list.map((item,index)=>{ return ( <CSSTransition timeout={1000} classNames='boss-text' unmountOnExit appear={true} key={index+item} > <XiaojiejieItem content={item} index={index} deleteItem={this.deleteItem.bind(this)} /> </CSSTransition> ) }) } </TransitionGroup> </ul> <Boss /> </Fragment> 复制代码
总结:React动画还有很多知识,能做出很多酷炫的效果,完全可以单独分出来一个岗位,我在工作中用的都是比较简单的动画,用 react-transition-group
动画已经完全可以满足我的日常开发需求了。如果你想学习更多的React动画知识,可以看看文档或者书。
学完这节,React的基础知识部分就到这里了,下节课开始讲解 Rudex
的知识,希望你能跟着技术胖继续学习,一起努力进步。
技术胖315集视频镇楼
1-React(新版)基础免费视频教程
2-Flutter基础视频教程
3-Flutter 20课小实例练习
4-ES6免费视频教程(18集)
5-前端必会的 Nginx免费教程 (共11集)
6-TypeScript免费视频教程 ,Deno前置知识 (共15集)
7-Nuxt.js免费视频教程 开启SSR渲染 ( 共11集)
8-CocosCreator 从基础到实战免费视频
9-挑战全栈 MongoDB 基础视频教程 (共21集)
10-挑战全栈 Koa2免费视频教程 (共13集)
11-React免费视频教程-入门和组件 (共11集)
12-React免费视频教程-表单的应用 (共4集)
13-React项目构建和路由 免费视频教程 (共10集)
14-Vue2.0视频教程-内部指令(共8集)
15-【第二季】Vue2.0视频教程-全局API(共9集)
16-【第三季】Vue2.0视频教程-选项(共6集)
17-【第四季】Vue2.0视频教程-实例和内置组件(共4集)
18-Vue-cli 免费视频教程(共3集)
19-Vue-router免费视频教程(共11集)
20-vuex免费视频教程(共6集)
21- Vue实战视频-快餐店收银系统 (共11集)
22-WEEX免费视频教程-从入门到放肆 (共17集)
23-Fabric.js 免费视频教程(共13集)
24-CSS3免费视频教程(共31集)
还在不断录制中................
以上所述就是小编给大家介绍的《掘金最污的 React16.x 图文视频教程》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 掘金小册写作参考
- 使用xposed更改掘金的侧滑退出的触发范围(左撇子,掘金的这个侧滑退出的体验一言难尽)
- 掘金小册优惠折扣一览
- React Demo Four - 掘金
- 为掘金小册添加目录
- 掘金翻译计划月报 — 2018 年 11 月
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。