00:00
好,各位,我们再讲第五个扩展点,叫做context。这个词呢,直译过来呢,我们看一下它的含义啊。Context。有环境上下文来龙去脉的意思。那我给大家讲的这个context呢,主要是一种用于组件间通信的一种方式。同学,我们在九里边会整体给大家总结一下组件间的通信方式啊,什么叫组件间通信呢?就简单来说,同学有个A组件,有个B组件,他俩之间想传递点儿数据,那这就叫做组件间的通信,你把什么东西给我,我把我收集的用户的什么信息给你,这就是一种通信。那我们所讲的context特别适用于组组件与后代组件间的通信,那么你就得明白什么叫组组件,什么叫后台组件,你比如说有一个组件叫做A,那A里边呢,我再写一个B,那请问各位A和B什么关系啊?是不是父子组件呀?好,里边如果再有一个粉色的C,那我问各位B和C什么关系父子?
01:18
B和C是父子A和B什么关系?父子A和C呢?这就叫做祖孙组建,或者说祖组建与后代组件。那我问一下啊同学,如果C组件里边还有一个组件,它叫D,那我想问你的是A和D叫啥呀。你叫祖孙组件可以,或者你叫做组组件和后代组件也行,那我们所讲的context就专门适用于A组件和C和D之间通信,说老师呢,A和B,那不能用这个呗,能,但是A和B它有一个更简单的方式,是不是叫做props呀?那父子之间对不对?用props不就得了吗?好。
02:04
那回到我们的代码当中,四呢,折叠起来,我们右键新建一个五下划线。诶,这叫什么呢?叫做context,好,右键新建一个组件,index.js叉用类组件创建啊RC。打快rcc好了,那么APP里面换一下引入不引入四了,引入5CONTEXT来到这,呃,我让这个组件呀同学叫做。A那叫A组件,好,我在A组件的下方呢,我在定义一个B组件啊,叫做B。把这个终端关掉,我在B组件的下方呢,再来一个叫做C组件,哎,我定义了三个组件对吧,各位一个一个来吧,那么A组件里呢,我让他有一个自己的状态啊,A组件就属于副组件了啊,就是级别比较高的那种,好比如说它里边有一个username啊,叫做Tom。
03:10
好,他在这儿首先呀,先说出一句话啊叭如说先说出一个H3叫做我是A组件,我的用户名是,或者这样吧,别写一行,先告诉人家你是A组件,在后边再来一个啊,再来一个别写死SPA了,来一个H4标签吧,嗯,H4叫做我的用户名是写好了this.state点是不是username呀。好,那么是这样啊,我想让ABC啊形成这种关系,这是A,这是B,这是C,那你说得怎么办呀。那你在B组件里面是不是得用到C,那么A组件里面是不得用到B呀,那所以说这样同学我把B组件呀,给你写在这儿可以吧,那你说我这么一写A和B啥关系呀,他俩父子了,好,那我把这一堆东西同样的拿到B组件里边来,首先告诉人家你是B组件。
04:17
啊,这就不是我的用户名了,那咱就得这么说我呀,从A组件啊,这个接收到的,写上用户名啊,然后冒号是吧,咱得这么说啊,你看我是B,我从A那接到的用户名是这个,那同学这得用谁了呢?是不是得用C了呀,哎,好了,那C跟他是一样的,这一堆复制来到这儿粘贴说我是C组件。我从A组件收到的用户名也想展示到这儿是吧,那这会儿就不再渲染别的组件了,到这儿就结束了,那这个用户名呢,我先拿问号代替,那这个用户名呢,我也拿问号代替,因为无论是B还是C,根本就没有收到A传的东西,因为A还没传呢,那我给他们呢,分别写几个类名啊,就是不写也行,我们看一下啊,同学们APP里边已经说了,渲染的是五,那来到这儿呢,是吧,我们这也确实写东西了,好了,看一下页面吧,啊,刷新一下同学觉不觉得在这儿啊,你就有点说不明白他们之间都是啥关系了。
05:28
你这一看,还以为ABC3个人是啥是兄弟呢,其实整体是谁呢?来画个图,整体是A完里边这一堆吧,算是BB里边吧,咱知道是不是用了C呀,但是为了能让大家看的更明白一点啊,同学,请允许我写一丢丢样式啊,我在这来一个class name,它不是最顶级的那个吗?那我就这样让它叫做parent啊,Parent啊,副组件好,那把这个呢拿回来,那B就是属于什么组件呀,应该是child对不对?孩子child child,那这个呢,把它整个复制,C就属于孙组件了,或者说后代组件了,GR grand是吧,I grand,那来,咱写点样式啊,我临时写点index.css啊,那都有几个类名呢,一个是parent,一个是child,一个是grand,那都给它拿回来,前边呢,都得加上这个点。
06:29
是吧,那我先粘过来吧啊,这儿这儿这儿都得来个点好了,先写写parent的,Parent呢,让它宽宽一点,让它是500PX高呢,这个就不写了,让它随意吧,这个高度哈,让它自动的就撑开吧,然后呢,Child给它来一个,但是我给parent一个背景吧,BAACC,让它是orange橙色啊,那么这个孩子这个宽度呢,我让他呃,100%吧,整个都撑开是吧,给他来个背景色啊,这个子组件的背景色呢,让它是天蓝色,Sky blue啊,然后咱再给这个孙组件再给他写点,让它的wise也是呃,100是吧,100%整个都撑开,这儿呢,也是100%,好,那在这儿怎么写background color,给它换个颜色,比如说让它是灰色吧,啊,灰色。
07:22
好,那我来到这里边是不是得把这样式引入啊,各位,那走import,引入当前目录下的index.css,回到页面我们看一下效果来,诶,大概就是这么一个形式,我再调整一下,我让ABC呢,在四周啊都留出一个攀顶,让大家更能看出来他们三个呢是父子孙的关系,回到这儿改一下我们的这个样式,我在这儿来一个攀定,让它四周呢都是5PX啊,不仅是父组件要有子组件,还有我的孙组件都要有。好回到页面刷新看一下效果,哎,这回看的就能明显一点了,是吧?我让这五呢,稍微再大一点,让它是八吧,啊,这也写成八,这也写成八,好了,保存来到页面刷新看一下,这回就明白了吧,同学,这是父啊,这是子啊,那这个呢是孙,他们是有一个包裹关系的好嘞,同学,我。
08:22
想让B组件收到A组件的名字,那咋办呢?回到这个里边来,我们的代码里边,你想给B传非常简单,那就是username等于this.state点是不是username呀?那你B接到了之后呢?那你这是不是就可以做展示啊,this.props.username保存回到页面刷新看一下效果,Tom这是不是收到了呀?好。同学,那你说如果此时此刻呀,我告诉你C也要用,那其实你应该能想到这么写,就是逐层传递呗,对不对啊B反正我收到了,那我给C呀,那C收到了呢?那这就划括号,接着写this.props.username是吧?那其实就是这一堆,前面这删掉保存,我知道你一刷新,这样是可以实现效果的,它给了BB,又给了C。
09:23
同学,这是B在用,顺带着B也就给C了,那我想问的是,如果B不用呢?B不用说老师没事儿,不用呢,他也接一下啊,没事儿我先传给BB再接一下,同学,那我问你如果七层呢,你咋传,逐层传,你把七层组建每一层组件都打扰一下吗?不太合适吧,哎,所以说就得利用了我们的context。好同学这块呢,先给它删掉,那怎么用呢?啊,我不需要给B传,因为B也不用啊,那所以说C这你也甭想通过这种方式接到,对吧,你只能写几个问号,周老师,那现在的效果那你看吧。
10:11
啊,A组件有名字,C组件要用,但是B不用,B要想用的太简单了,Props直接过去了是吧?那这怎么办呀?来同学,我们在C组件里边呢,进行一个输出,我输出一下this,请你告诉我这个this是谁啊,回到这刷新一下啊,那这一呢给它删掉,同学输出这C是什么呀。是C组件的实例对象,你说对吗?State props res这三个我们是不是都用过了呀?哎,那这是谁呢?就是我们要用的这个context的,这个context就专门用于组组件和后代组件间通信,怎么用呢?看一下我们的课件。首先第一步你要创建一个上下文对象,也叫做contact的对象啊,借助哪个API呢?叫react.create context。
11:10
那这个容器必须得放在ABC都能访问到的位置,就有一种感觉,A想给C传东西,那其实呢,就是放在了一个公共区域,但是这个区域可不是Rex啊,要比Rex简单得多。啊,那所以说你得创建这么一个容器对象,那来吧,我们回到代码里,我们自己去写,我放在最上方。啊,统领全局的这么一个来cost定义,那叫什么呢?想传的是不是名字呀?哎,那你就写上叫做username context,细心的同学注意了,我的首字母居然大写了,这是为什么呢?先大写着,一会儿你再看啊,react.create create context。
12:00
Contest,好。那么这就是创建一个用于保存用户名的上下文。或者说呀,你可以不写的这么具体化,因为目前我就保存一个用户名,对吧,同学们,万一以后咱保存点别的呢,那所以说我这么写吧,啊,就叫做my context啊,My contact,我的上下文好创建context对象。创建完了吧,那接下来呢,你注意你想给谁传递。这是A,你是不是想给C传递呀?回到我们的总结里边,注意了,子组件要用一个东西包裹起来,这个东西就是你刚才所创建的什么什么context,它身上有个属性叫做provider。同学,这词你熟悉吧?我们在讲Du的时候,是不是说有了react-redux,你用了provider就能给所有容器组件都传递一个star?其实它也是用的这个原理啊,但只不过呀,跟人家react里的实现不一定完全一致啊,当然也是可以这么玩的来。
13:18
那所以说呢,回到我们的代码当中,同学莫紧张,你是不是想让这个B组件及其他的后代组件都能拿到你的这个用户名啊,那你就得需要这么做,明明直接可以写B,但是我不写,我偏要写什么呢?这个my contest.provider啊,这是一个标签啊,各位啊,来说老师,标签还能这么写吗?My contest,然后点provider。同学,如果你要觉得每次还得在点写起来特别麻烦,你完全可以这样做结构赋值,从这个my contest身上取出谁呀,Provider,这回你知道为啥我要大写了吧,因为组件标签它得是大写的,哎,然后再点provider,你这么去查找provider这个对象,行,那或者呢,你直接像我这么写,提前给人家拿好了,哎,Provider走。
14:17
同学,Provider有什么含义啊?是不是有供应者养家者的意思,咱之前是见过的,好,你把你的B组件包在这个里边。同学觉不觉得这种写法像极了当年学习re的时候?好,你是不是得给他传点数据啊?直接写吧,Value等于想传啥?用value这个属性名想传啥老师我想传用户名,那就写嘛,this.state.username那你频繁的使用username,那就不如结构不值this.data取出谁啊,Username那这呢?Username那这呢?Username,好了,说老师我这么写完了能怎么着呢?你这么一写完,同学B组件以及B组件的子组件,这个C组件就都能收到你所传递的用户名了。
15:12
啊说老师是吗?那在哪儿收呢?就在这儿收。就在组建实例对象身上的context属性上来,我们看一下效果啊,回到页面刷新,哎哟,可惜了,嗨,拿到的是空对象对吗?这是为什么呢?回到代码,我说一下。同学可能觉得呀,老师只要我在B组件外边包1PROVIDER,我写了个value等于username,那我就知道了,老师叫B组件及其B组件的所有子组件就一定会收到这个username,不是的。不是说所有的就都收到了,是谁声明谁能使用,啥意思呢?不是说你这一包裹这里边儿就E就全都有了,不是你得跟人家说说,其实我想用,你得举一下手就可以了,那怎么举这个手呢?同学,你是B想用还是C想用,你告诉我其实B也能用,各位B在这儿一会儿我们也能拿得到这个B,但是主要是说想感受一下,这是A,这是B,这是C,中间隔着一个人这种感觉是吧?那怎么声明呢?非常简单。
16:28
回到我们的总结里,给大家写好了,你需要加上这么一个东西。声明接收contest,如果你不声明不好使,必须得声明,那就回到代码当中。哪个组件想要C来C去声明,必须得用static加一个静态属性,这个属性的名字呢,就叫做contest type。Context type什么意思呀?上下文类型,你想接收哪个呀?什么类型啊?是你刚才创建的这个I,必须得把它写在这儿,你这一写不要紧,来吧各位回到页面刷新看效果,Tom拿没拿到,拿到了。
17:08
你真要是拿到了,我问各位,这是不是就也能写了呀?怎么写呀?this.contest是不是可以了?同学,我问一下在这打扰B组件了吗?B组件还是当年的自己干干净净,但是C组件是不是收到了呀?那我问一下你说B能不能收到呢?我们验证一下this点哎this.context我们瞧一下啊,来到页面刷新啊,看一下效果,B是收不到的,为什么呀?因为你没声明,你没跟人说你要,你如果跟人家说了你要,那走说了吧,保存回头刷新。B也是能拿拿得到的,但是父子之间啊,说一下真没这么玩的,父子之间props是这个世界上最简单的一个方式,好爱说老师那就能,那就这么写了。
18:02
啊,是的,但是有一些细节上的问题,我想问各位的是,你觉得这能不能换名呢?我叫Y62,能不能行啊?回到页面刷新,同学不可以啊,他说了,你想让这个东西起作用,就必须要写Y6,还告诉你呢,你是不是忘了呀?所以说同学不允许你改名的,奏叫Y6是吧?哎,奏叫Y6。好说老师,那明白了,那就能这么用了呗,就以后我想给谁就一包裹,这个人以及这个人所有的后代组件就都能收得到。是的,但是得有个前提,你得声明接收contest,写好声明,哎,接收contest,那还有一个细节上的问题,同学。如果呀,我这里边儿还有一个属性叫age,年龄18岁。我想把这个年龄也传给C组件,那怎么办呀?老师明白了,我再创建一个,哎,不用一个就够,一个就够。
19:03
那咋办呢?瞧着你这个value非得写成就一个字符串username呀,我这么写啥意思,Username冒号username age冒号age,那你这就得取出来,对不对?同学,我这么写啥意思呀?哎呀,你传递的Y不再是一个字符串了,而是一个对象,外边的花括号那是分隔符,里边那花括号那代表对象,那你说这么一写,这么一写是不是就结了呀?哎,所以说可以传递对象的很多东西都是可以带过去的哈,好了,来,那C这儿呢,声明接收,但是你这儿就得注意了,你这个context可就不再是一个字符串喽,那你想展示用户名,可就得点继续写什么啊内幕,那你想展示年龄,那就得逗号来写上年龄啊,是写上花括号this点。context.a哎,我们缩进一下看看效果,来到这刷新。
20:05
稍等A、用户名年龄,用户名没收到,检查一下吧,不叫name,叫username,保存回来刷新。看一下效果啊,诶Tom,诶是吧是吧,来了呀,哎,OK,那你在这儿啊,也不用写的这么复杂,同学你说是不是可以提前解构赋值给他拿好啊this.context拿谁呀?Username还拿谁呀?那这就省心了,直接写username,这儿直接写什么呢?A好了。啊,回到这儿刷新看一下效果,老师OK了,学会了,明白了以后呢,就这么写了,哎,那我再问你一个问题C,万一不是拿类写的咋办?哎,同学你想啊,C这个组件如果不是拿类写的,你能写这个吗?如果不是拿泪写的,你有意思吗?哎呀,这是个问题啊,来。
21:02
注掉,把C组件写成函数式组件走。把里边的return是不是拿过来走。啊,那这类名啊,样式的类名还是这个,但是在这儿你是不是拿不到这些东西了。由于C是函数式组件,你能写这个吗?不能,你有this吗?没有,那所以说就拿不到了呀,那怎么办呀,没事儿,我们还有另外一个办法。来,回到我们的总结里边,这就是我们所说的第二种方式,来,我们读一下。函数式组件与类式组件都可以用第二种方式。第一种有局限,只能是类式组件去使用,那么第二种就不同了。你读一下这同学看啊,什么什么context,其实就是刚才你创建的那个context容器,对象从他身上不仅能娶到provider,其实你还可以娶到一个人叫customers。
22:10
这个呢有供应者养家者的意思,那它呢,其实就有消费者,哎,就有点儿感觉像花钱者这种感觉,所以说它的使用方式就是获取到这个customers,消费者之后呢,在里边直接写函数,函数会收到一个参数,这个参数就是你在上方所提供的数据值,然后在这儿就直接写你要写的内容。那回到我们的代码当中,需要我们做的就是在上方从他的身上再多拿一个customers。拿到这个东西之后呢,来往下往下你就找到你要展示的东西,这是不是你要展示的东西啊,那所以说这一堆先给它删下去。
23:01
回车写cos这个组件,回车里边写一个函数,函数会收到一个value,走,你在函数里边开始写返回值吧,老师,那我返回什么呢?你想展示什么吗?你不是想展示你收到的用户名冒号吗?那就写用户名是什么呀?说老师,那这Y6是什么呀,哎,也是哈,我们先看一下这个Y6吧,走。保存了啊,回到页面刷新一下看效果,Y6是啥呀。你传的是什么,他收到的是不是就是什么呀?那value都握在手里了,来接着写吧,这怎么办呀?Return返回值,那你是不是想之前在这直接写文字啊?哎,那你就写模板字符串啊,来吧,到符画括号拿谁value value是不是那变量啊啊,那个对象把点是不是username呀?啊,那你还想再说出一句话逗号,那就是年龄是然后呢,Dollar符划括号写上value点谁呀A。
24:08
这不就拿到了吗?保存来到页面刷新看一下效果,Tom年龄是不是都拿到了呀?哎,这会儿呢,大家要注意啊,由于啊,你已经开始写这东西了,你里边所有的呢,都算GS的表达式,但是我这个文字的外边啊,还不想包裹标签了,因为原来我确实没包裹,同学这儿如果你想包标签,那就太简单了,你看着咱就不用这么费劲的span标签可以吧,Span,然后里边怎么写呀,那就是划括号直接写啊y6.name啥的是不是就可以,但是问题是我不想再包这层span了,那你就得这么写。箭头函数吧,函数体只有一句吧,要默认返回吧,所以说这一堆都可以写成这个,那这儿可以毁成一行,这就可以了,函数式组件就这么用。
25:01
我们捋一捋啊,同学,你想用context去传递数据,那你就必须得引入这个人,至于说它引不引入,我得看你用的是不是函数式组件,对吧?如果你用的是类似组件,你不觉得就把这个属性咱就用上了吗?z.context对不对?哎,组件实力身上的那些东西,没有一个是平白无故设计的,都是有自己的含义的,诶,这就是context。特别适用于什么?祖组建和孙组建,或者我们说后代组件间通信适用于A和C,那么从图上的体现就是逾越过去了B直接给了CA,就是这么回事。好,那回到课件里边,我们有最后一句话。在应用的开发当中啊,我们一般不用contact,一般都用它去风筝react里边的插件,想想我们所学的那个react杠,Redus里边是不是就用了provider这个技术啊,哎,好,那这小节呢,我们停一下。
我来说两句