00:00
好,各位按照顺序呢,我们就把课件上的最后一章第七章redux讲完了,可能同学挺开心的,老师终于呢,我把七章都学完了,那么基础我是不是就都学完了呀,没有,课件虽然到最后一章了,但是基础并未结束,因为我们都知道啊,React呢,时不时的就出现一些新的小知识点,推出一些新的API,所以说接下来呢,还得给大家扩展几个点啊,React新提出来的这些点啊,那我们就脱离课件了啊,各位就不再看这个课件了,我们把课件呢关掉。啊,打开我们给大家的文件啊,React全家桶课件,这里有一个react扩展,哎,是我刚给大家放进来的,你们各位拿到的文件里边肯定是有这个的react扩展,诶,我们打开。这是一个markdown文档啊,我们并没有用word文档去总结啊,用这个让大家能看起来轻松一点,我们一共呢,给大家扩展九个小点,其实第九个呢,算做一个总结,那我们就一个一个来吧,啊首先看第一个关于site state,那今天呢,我们重新认识一下这个set state。
01:13
Set state更新状态呢?同学其实是有两种写法的。哎,只不过呢,我们之前总用一个,你就觉得诶好像是不是只有一种写法呀,其实有两种啊,来同学先最小化这个笔记,我们把所有扩展性的内容呢,我新建一个文件夹啊,右键我选择这此处打开命令行,我也肯定得在脚手架里面写,你说对吧,所以说我创建一个新的脚手架吧,怎么样,同学们c create杠,React杠。APP,哎,然后再写上给它起个名字吧。毕竟是react里边扩展性的内容是吧,那我就这样写吧,React啊,然后呢杠,然后再来一个这个,呃,下划线嘛,因为包的命名呢,是不允许出现杠的,但是下划线是可以的,对吧?啊,那扩展extension行吧?哎,我叫这名字啊,敲回车啊,等着他把这个工程初始化完毕。
02:16
那经过一会儿等待,一个新的工程就生成了,哎,我们把它呢关掉在这儿呢,React扩展性的内容都在这儿呢,打开。这个里边的两个东西我要删掉,一个是点G,一个是get a闹,因为呢,我们讲的课最终是以压缩包的形式把代码给大家,所以说我也就不建立本地的仓库了,右键选择删除,好,这两个文件没了,把它放在这是我们最后用的一个文件夹了,右键我们选择Vs code的去打开它,首先呢,我们检查一下,看看这个工程啊,能不能正常的启动打开终端n PM start我们看一下啊,稍等。
03:08
控制台呢,也看一下,OK,刷新是没问题的,好,这个工程呢,可以用了,那我们就把浏览器关掉,把这个终端里的server也停掉,精简一下这些代码,Public里的东西从这到这儿呢,我们都不要了啊,APP里的东西呢,从这到这我们也不要了啊,开始自己写public里呢,我得写一个index.atml好,那src里呢,得有一个app.js其实写JS叉行不行啊,也可以,因为APP不也是一个组件嘛啊,反正这个写与不写都行,那那我们在这儿呢就不写了,因为脚手架呢,刚开始他也没写是吧,没写GS叉写的JS,好了,新建一个index.js,嗯,准备性工作呢都做好了,首先第一步来到index里边,我是不是得引入react核心库啊,From react OK,然后再往下我得引入react do,用于去渲染do from do。
04:08
OK,还得引入谁呢?APP啊,那个跟组件当前目录下的APP进行一次渲染,React do.render渲染的是APP did不是T了,是root啊,好,OK了,把它呢,关掉,来到APP里边rcc,我们去创建一个组件,它没有识别啊,那你就保存一下,把它删掉,然后再慢一点敲rcc。诶还是没有是吧,那再把给它删掉文件呢,咱也给它关掉啊,再打开再来rcc哎就有了,有的时候呢,可能反应慢一点啊,APP里面我们写上点点点点点点点保存关掉,折叠起来,来到index里边写好固定的结构啊这写好了叫做react扩展知识啊扩展的内容div准备好,一般我们都叫做root好了,东西都准备好了,看看我们改的这个能不能启动呢?啊输入n PM start回车。
05:13
稍等,等着它启动一下。控制台呢,也准备好。好,是OK的,没问题的,那么我们就把这个关掉,然后这里边儿有read me嘛,各位read me啊,我就都删了去啊,全选删了去,Read me里边我写什么呢?我不是给了大家一个扩展知识的文档吗?打开那文档就是这个全选啊,全选复制。最小化来到read me里边粘贴,哎,Read me里边写的就是我给大家这个笔记啊,跟我之前给你那个markdown是一样的啊,来给它关掉走,那么我们开始写吧,先学第一个东西,就是set state更新状态啊,其实它有两种写法啊,不难,我们看一下啊,来最小化,这怎么办呢?Src里边,我不想直接在APP里边写任何的东西啊,我这样新建一个文件夹,Components,我把所有我讲的那些组件都写在这儿啊,然后新建一个文件夹,这回呀,我就不写什么count,什么person啥的了,我用这种方式去命名啊,一下划线set state就证明我讲解的不是别人,是讲解的set state的写法,对吧?那在这个里边我创建一个组件,你比如说叫做index.js叉可以吧。
06:40
A,然后rcc啊又不出了是吧,Rcc好了,那这个名字呢,同学我就随便写一个吧,啊,最好别叫state,因为这属于一个关键字啊,我就叫做DEMO,就叫DEMO组件完全可以吧,嗯,DEMO点点点点点点好。写完了这组件啊,也暴露了,那关掉在APP里呢,你就不需要自己写这个了,APP里边我引入刚才我的那个DEMO组件,就写DEMO啊,然后from啊,当前路径下的components下的谁呢?这个set state。
07:15
啊,是我这文件夹呀,同学叫set state,但是我那个组件不是随便起名字嘛,对吗?我就叫做DEMO了,因为接下来我们写的就不是一个成型的案例了,是一个一个一个细小的点知识点啊好了,DEMO准备好,那么关掉,不出意外的话,浏览器上应该有效果了啊,回到浏览器啊,刷新看一下效果,稍等啊刷新一下,嗯,没有效果吗?再来控制台检查啊,它出来了,刷新的可能是有点慢,来再刷一下,这回就有了控制台啊,我们也是开好的来最小化页面,接下来开始讲这个set state。首先我得写点基本的这个样式和结构哈,那来,我先写点结构吧,样式咱一会儿再说,同学,我还是拿球盒那个案例啊来举例子,为啥总用那个呢?因为那个东西啊,大家都明白它是什么需求,写起来还简单啊,能够最容易的把知识讲完啊。H1叫做当前求和为为多少我不知道,那是不是得有自身的状态呀,各位,哎,走着,State等于,嗯,Count,对吧?和是几呢?零那这就有的聊了,这直接就这么写吧,this.state.count OK,啊,看看能不能读出来啊,稍等,等着它编译,编译完了回到浏览器刷新。
08:37
啊,是这样的零,那我有一个需求,就是这有一个按钮,点它就能加一啊button叫做点我啊然后呢,加一这按钮是不是得加事件呀?哎,On,大写的click等于那加就写吧,this.increment对吧?哎,或者啊,你嫌凡同学,你写ADDDDA也行是吧?啊ADDA就抄这个吧,这单词简单,ADDADDA等于走来加一同学。
09:05
没有让你选说加几,你只要点就加一,那我们一般是不是分两步做,第一步我们说获取原来的count值,你说对吧?那么第二步呢,那就是更新状态是不是就可以了呀?来,那咱先获取原来的count值,那走着应该是this.state点拿出原来的谁呢count来更新状态吧,咋写来着?this.site state同学,我们根深蒂固的一个想法就是set state里面是不是传一个对象。哎,对象里边说明白,你要改谁,我要改count来值,告诉我这么写九,那是不是就写死啊,我说要加一,那count是不是得加个一呀,好,那我们看看啊,它能不能完成这个功能呢?回到页面看效果来点击走,是不是完全可以加一啊啊最小化页面同学,这就是属于set state的第一种写法。
10:01
其实啊,Set state还有第二种写法。啊,那第二种怎么写呢?就是里边啊,它不再传一个对象了,它传什么呢?它传一个函数。爱传一个函数,我们回到笔记里啊,同学,按照笔记的顺序我们去说,走看这啊s state其实呢,它能传两个参数。稍后你再想这个啊,说还能传一个函数,先把第一个搞明白了。其实就你之前写那个set set直接传一个对象同学,那都是你省略了一个人,谁呢?第二个叫做call back。啊,我们管这种形式叫做对象式的set state,因为这里边你传了一个东西叫做state change。State change是啥呀?读嘛,非常简单,State change为状态改变对象。它不是一个一般的对象,它是一个状态改变对象,为啥叫状态改变对象呢?因为该对象可以体现出状态的更改,哎呀,就是一个概念性的绕回到代码同学,它就叫啥。
11:06
老师他是对象,再再准确点说啊,老师状态改变对象,对,为啥叫状态改变对象啊,因为通过这个对象我能瞄出来你要怎么改这个状态,你要把状态变为原来的值加一,哎,这就叫做状态改变对象,回到我们的笔记当中。同学,其实还能传第二个参数。是一个回调。叫call back。说老师那为什么用方括号括起来呢?方括号的意思就是可选参数。可选可不选。那我们之前回到代码里面,其实是不是一直都没选呀,其实是可以选的。说老师,那这函数有什么用呢?这里边儿就涉及到一个坑。就是react在帮你更新状态的时候,其实它是一个异步的更新。老师,什么意思呢?没懂,瞧着第11行你干嘛了?老师,我改状态了,诶对,我想在第12行看一下你改的状态。
12:00
同学,我问你第11行执行完了,是不是才能执行第二行吧,第12行吧,对。那第11行执行完了,你的set state是不是掉完了呀?那理论上我都掉了,Set state react是不是得帮我去改状态呀?OK,那好像第11行状态就改完了,那改完了之后,同学,我在第12行是不是完全可以输出看一下呀?来写上叫做12行的输出逗号,咋写呢?this.state.count你不是在第11行刚改完吗?那我12行我就想看一看呀?啊,那你看去吧,稍等编译回到这儿刷新。现在是零对吗?哎,点击加号走,同学注意看啊,状态变成啥了一可是。这输出的穴是什么呢?零。哎,说老师这我理解不了了,这这这理解不了了,那第11行都调完set state呀,那这到底是改了还是没改呀。
13:00
我按照12号来说的,他没改啊。但是在页面上来看,好像他还改了,那这到底是,哎,那说一下啊,同学你听我说是这么回事,11行你干嘛了,我调set state,你为啥调set state,我要改状态,哎,好同学接着往下分析,你要改状态,你是不是才调set state?你调set state之后,是不是得是react帮你去改那个状态的呀?嗯,对吗?同学。Set state本身就是一个同步的方法,由程序员亲自在主线程上调用的,对不对?OK react说明白了,你调set state了,你告诉我了,要把那count值改为原来加一,明白了。但是啊,我一会儿再帮你做,哎,这个问题就出现了。这个set state确实是一个同步的方法,我没说它不是,确实是一个同步的方法,只要程序员敢加小括号调用,立刻就在主线程上运行,根本不等,Set state根本不等,但是set state引起react后续更新状态的动作是异步的。
14:09
啥意思,你是掉了,我也没说你没掉啊,我也没说set state是异步的呀,是set state掉完了之后引起的后续动作是异步的,React说等会儿吧,一会儿我帮你改,你先往下执行,你就一直行,诶你就一输出完了,这就是零。你输出完这零了,React说来吧,我帮你改状态,诶给你改成一,所以说嘛,页面上看到的效果就是这样。啊,这也正是他官网里边所形容的那句话,React状态的更新是异步的。哎,E补的好来。说老师那我咋办呢,我就想改完之后我就想看一看。那你就不应该在这儿去输出,你这输出的一定是零,说老师,那我在哪儿呢?来这行先住掉在哪儿呢?在这儿他不能传一回调吗,传进去。
15:05
哎,传进去好了,那问题来了,这个回调什么时候调用呢?这个回调什么时候调用啊。它是一个回调,你定义的吧,嗯,你没执行吧,嗯,最后调用了吗?调用了是回调不是。问题是这个回调什么时候执行呢?回到代码当中啊,咱的总结当中,你读一下同学,Call back是可选的回调函数,它在。状态更新完毕,并且界面也更新后,也就是render调用后,它才被调用。哎,也就是说呀,同学你想在第11行改状态,完了,紧接着下一行我想看一看,这是不行的,因为是一个异步的更新,对不对,好。那在这儿呢,就不一样了。你这不是给了一个回调吗?你注意这个回调所调用的时机,是在react帮你改完状态,帮你调完render,随后人家才去调的这个回调。
16:02
那同学你想render都掉完了,页面是不是早就更新完了呀?那状态是不是也早就更新完了呀?所以说在这个里边,如果你进行输出this.state.count你是可以拿到一个最新的值的,所以说同学这回调有什么用啊?这回调就是让你更新完状态之后,如果你想拿,你应该在这儿拿它就是一个准的了,来我们看一下效果,刷新点击咋样,是一吧。回到代码,所以我们说呢,这个回调呢,是可选的一个参数,如果你有这个需求,说我改完了之后呢,我就想看一看,那你需要在这个里面去看,才能看到一个最准的是吧?哎,那同学刚才我所说的这么多呀,都算作是第一种写法set state呢,还有第二种写法,我们管这种写法呢,叫对象式的set state。因为什么呢?你确实写了一个对象嘛,那其实它还有一个东西就是函数式的s state啊来这个console呢,咱改一下啊,少东西了,好,那函数式的怎么写呢?我先把这一堆呀给它注掉,前边加一个注式,这叫做含这个对象式的site state好。
17:23
说完了这之后呢,我们再说说函数式的,其实也非常简单啊同学,函数式的。Set state非常简单,函数式子怎么写呢?This点儿set state直接调。调的时候呢,不再传一个对象了,那传什么呢?回到我们的总结里边看一眼,你传了一个东西叫update。Update是什么呀?往后读说老师他还有一个可选项,也叫call back,对,它也有这个啊,都有。来再读update,返回state change对象的函数。
18:01
你仔细再读一读,Update为函数,所以说update传的是函数啊,所以说它是函数式的S。那么这个update返回值是什么呢?返回一个状态修改之后的那个对象啊,也就是我们之前你正常不是把对象写在这儿吗?叫状态改变对象,这回不的了,状态改变对象作为update的返回值了。哎,而且update呢,是可以接收到state和props的。那么callback呢,是一个可选的回调,这不说了是吧?哎,状态更新完了,页面也render之后才被调用,来我们写一写大家就知道了啊,回到这儿走,同学传一个啥传一个啥啊,传一个函数走。这个函数是不是得有返回值啊各位啊,返回什么呀?嗯,Retn,你比如说我返回这么一个东西,Count冒号99,这啥意思呀。正常来说吧,你site state可以直接把这个COUNT99是不是写在这个位置,但是现在不是了。
19:02
我要写一个函数,函数调用的返回值是这个对象。啊,那你也能完成状态的更新,我们看一下啊,回到页面点击一下是不是变成99。但是这时候啊,你可能会觉得老师这麻烦呀,这不对呀,这东西还不如我直接塞写这个来得直接了呢。但是你要注意啊,我们的要求不是把它改成99,我们的要求是把它加一。那我跟你讲这个site state,如果你传函数,这函数能接到两个东西,一个叫做state,一个叫做外部传来的prop。啊,那你比如说啊各位,我来到APP里边,我在渲染这DEMO的时候,我传了一个XX值呢是101好。然后在这呢,你是不是能接到一个state呀,那你这个state呢,就是这个里边的,哎,这个状态就是它啊,那所以说你想把它加一,那很简单,你就写state.count加一就可以了。
20:05
啊,来,咱conslo一下,看看他所输出的那两个人到底是不是state和props,来,我们试试啊。回到页面当中,刷新,点击加号,同学,这是谁呀?State这是谁呀?Props哎,所以说同学set state,如果你写一个函数,它也是有点优势的,因为怎么的呢,它能拿到state和props啊,然后在这里边呢,哎,你可以这么写count,它的值是原来的count加一。同学,您觉得优势在哪呢?你原来是得进行这一步,就是获取原来的状态值,但是这回呢。这回呢,不用了,人家帮你把状态传进来了,你说对吧,而且这段代码呢,咱还能精简,精简函数体,只有一句吧。啊,返回的还是对象吧,而且这个props如果你说你要不用,其实也可以给它删掉,你说对吧,但是你心里边一定要知道它是能收到一个props的,但是我不用是不是可以删掉箭头左侧一个参数小括号是不是省略了。
21:08
箭头右侧只有一句函数题,还想默认返回一个对象,咱之前都聊过,那你说这怎么办呢?是不是得写一个小括号,把它花括号丢里边去啊?同学们,你看一行代码我是不是就完成了加一呀?哎,回头看一下效果刷新走着是不是完全可以呀?哎,回来,所以说这就是函数式的set state。那说老师明白了,函数式的set state呢?可以不用获取原来的状态值,他把这个东西传进来了,要是对象类型的,我还得自己获取一下原来的状态值,然后在这再用,对啊,这就它俩的区别。那他俩使用的原则是什么呢?我们回到总结里看一下,其实非常简单啊,同学,首先明确第一个事儿,对象式的set state呢,它其实是函数式的set state的一个简写方式。对象式的set state是函数式set state的一个语法堂。
22:04
那回到这儿来看。是不是获取原来状态呀,呃。然后呢,是不是set data直接写一个对象吧,那你这种形式其实就是这种形式的语法堂,你不就是直接把这个东西给他写过去了吗?但是我们用的更多的是不喜欢用这个语法堂啊,直接写对象,而且一般的时候同学我们这个回调啊,是不是也不传啊,但是我在这必须写上,让你知道说能写这回调的。啊,这叫做函数式的S,来,再往下看,同学使用原则如下。如果新状态不依赖于原状态,那么就使用对象的方式。什么叫新状态不依赖于原来的状态呢?你举个例子,同学。我现在不管你原来的和是几,我现在的要求是点击按钮和变成99。我不管原来是多少。只要点按钮和变为99咋办?回到代码当中。
23:01
你就不太适合用函数式去写了。函数式你怎么写?这是不是得写99?那你这也不收了,那是不是这么写呀。用函数式你是不是得这么写呀?已经最精简了,是不是也只能这么写了呀?对象呢,就不一样,this.s state来走,你要改谁?我要改count改为多少?99完事儿,你觉得哪个简单呢?一定是对象式的,对不对?这就属于典型的不依赖于圆状态,啥意思?你原来爱多少多少跟我没关系,你原来1万呢,我也现在变成99,这就叫做不依赖于原状态,但如果依赖咱撤回来,同学,你比如说我想让它的值在原来的基础上加一,那么您就需要获取原来的值,然后原来的值加一,对吧。哎,那回到代码当中啊,总结当中咱看一下,如果新状态依赖于原状态,原来是一,我是二,原来是二我是三,这就属于依赖于原来的状态,那怎么办呀?就建议你使用函数式的是吧,为啥呢?因为函数式已经把原来的状态传给你了,你直接在里边用就得了,那要是你自己用对象制呢,那你就还得获取一下,对吧?其实啊,同学也没那么较真。
24:15
同学,我把这段代码解开啊,你看着啊,我现在就想完成这个动作,就是一点就加一个,一点就加一个。同学,我非得获取一遍吗?其实也不用,那这样吧,这堆代码呢,我尽量不破坏它。为他住掉。来到这儿,同学你看我给你写一下啊。我更新状态依赖于原来的状态,但是我就不写函数,你看看能不能行,This点是不是set state来走同学,我是不是想改count的值,我是不是想让它原来的基础上加1this.state.count加一难道不行吗?难道不行吗?这么写太可以了吧?来点击加号,能不能加能回到代码同学,所以说呀,事情也不是说那么的绝对啊,你依赖于原状态,你就必须写函数,你不依赖于原来的状态,你就必须写对象,不是开发当中你可以随意的去选择纠正回事。
25:18
啊,那来在这儿呢,给这儿给大家保留,这函数还得写着是吧?哎,这是对象式的,一个是函数式的,没那么绝对,想用哪个你就用哪个,但是你要知道他们两个是都可以传一个回调的,如果你想改完状态之后啊,立马就看看这个状态需要在这个回调里边去读,否则你读不到一个最新的值,对吗?同学,但是更多的场景啊,我们不去做这件事儿的同学,就是啊,你在这儿改了,只要你的代码没写错,同学,状态人家一定会帮你改的,Render,人家一定会帮你调的,但如果你就非得有这么一个要求,老师我改完我就想看看,那么你不能直接看,要在这个回调里边看,那我问一下各位,这块我是不是没写第二个参数啊,我要写呢?同学,这是不是也可以传一个回调,哎,那在这里边呢,那你说我是不是可以can this.state.count是不是也能看到那个值啊,哎,来咱看一下啊,回到页面刷新点。
26:18
鸡走是不是也能拿到最新的值,哎,所以说那个毁掉啊,可传可不传在这儿啊,我就不传了,因为这一传呢,就明显显得这个函数式的S太恶心了是吧,哎,这小节呢,我们停一下。
我来说两句