React 2|学习笔记

简介: 快速学习React 2

开发者学堂课程【高校精品课-上海交通大学 -互联网应用开发技术:React 2】学习笔记,与课程紧密联系,让用户快速学习知识。

课程地址:https://developer.aliyun.com/learning/course/76/detail/15745


React 2


内容介绍:

一、处理 setState

二、制作 React 项目

三、小结

四、课后答疑


一、处理 setState

Clock 变得比较好用,所以是用这种方式来进行封装。

同时刚才说到 State不能显示的这样去设this.state.comment=’Hello’; .能够这样设只有一个地方在构造器,在其他地方都要用 setStat:因为只有 setState 才能去触发整个页面重绘的动作,而直接复制是不会重绘的所以在这个地方要用到 seStatet 。 setState 的方法里面,改变当前的时间的时候,一定要用这种 setState 方式来实现。
setState 本身也有可能是一步去更新的,比如处理 setState 之后,counter 的这个状态马上就发生变化,就让他重绘一下但这件事情能不能发生,这件事情被re-render接管,可能很难去控制它,只能告诉他我想要怎么样
那直接写 counter:this.state.counter+this.props.increment,是很难控制的。

主要是接管也就是说虽然完成了 setState ,但react可能因为某种原因,比如说现在比较忙,或者因为其他的原因导致内存不够,就先不会,但最还是会恢复一下这对你我们说就不是个好现象,也就是说你会看到表有时候走的快,有时候走的慢数字有时候闪的快,有时候闪的慢有时候半天不闪或者一闪就过去了。可能是这样,如果想要立即重绘就需要这样去写把它不是写成一个表达式或者直接它换掉,而是在这里面写成箭头函数或者普通函数在这个函数里面,
写他的状态发生了变化,或者是让它 return 新的发生变化的状态,只有这样写才能保证是立即做了一次刷新。刚才说的为什么不会马上执行,它出来的效果可能会是什么样子,比如说在构造器里面,设一个状态是这样的this.state={post:[ ],comments:[ ] ; } 然后在 componentDidMount 的第一个 Mount 里面,又有一个操作在设置状态,就是说通过 posts 的操作抓取后面东西,回来之后根据返回的值又设了一次状态,那完这些状态之后,就有可能会做一次所谓的合并在调用它的时候,它就有可能去做合并合并出来的是把他们状态就合并成当前这个状态。但是我们知道由于 state它是异步的去执行,再来看一下可能会出现什么情况。一开始 posts 是空comment 是空, DidMount ,也就是它绘制出来,去做了到后台抓取的动作,
回来之后把post里面放进去了一点东西,就是你可以放出 response 回来的一些东西,或者在底下通过另外一个抓取把 comments 里面放进东西,
要注意的是因为他们是彼此独立的,是彼此独立的变量,他们三个 state 都在设置,可能会带来问题一开始都是空的,然后分别只设置 post ,只设置 comments,然后就会告诉你在设置comments的时候,可能会导致 post 出问题。

因为他有两个变量,各设各的,互不干扰,分工明确, DidMount 里面又是异步执行的,所以就很难说到底谁先执行也许在后面执行看起来是在后面执行,但最后在异步执行的时候,会跑到前面去导致可能存在一些在的风险这个问题不用深究,因为大家现在写代码中可能不会有什么大的问题,只是未来一些复杂的程序的时候,会碰到问题假如说在这个代码里,除了写 setState 在后面想对 post 做操作

理论上 post 因为在他之前执行了,所以有东西了,这时候我拿到comments 之后对 post 做操作是可以但实际上会不会碰到这个问题很难说,因为进行了异步执行大家写代码可能会遇上这个坑,但我觉得现在这个阶段大家可能不太会碰到。
接下来说刚才我们说属性往下传 comments 属性可以传给 user infrom ,props 又传给armter 。

那么由此可引出 state能不能传?刚才讲了 state 提是它是私有的,因此就不应该
 state 再传给其东西如果你真想把 state 往下传送,可以把当前的 state 当成另外一个 state ,就像刚才看到comments 里包含comments infrom ; state 里包含armter ,可以把他的图片232.png

状态当成它的子构建的属性往下传,因为传下去子构建里面它是 props,它的状态不会发生变化,这种是可以的。那你想把它传下去,它会成为子的构建里面状态,这可能就做到了。我估计大家也没有这个想法,就是把这个 state 给它当成是component的一个 state 的往下传

应该大家不会有这个想法,如果你有这个想法,要注意只能当 props 传下去然后在子的 component 里去设它的state,能等于 props 里传进来的东西

这是我们看到的创建三个 Clock出现的效果是这个样子,就在demo9里就不进行演示了从这里面大家可以看到,我们把 Clock 独立出来的好代码得到了复用。然后我们谈一谈 React元素上面的事件事件和原始的 HTML 页面上的一些元素的事件概念是一样,就是在按钮上有个点击,可以在按钮上有鼠标滑过等动作。在 React 里面唯一的一点是他用的是驼峰编码,驼峰编码就是每一个第一个单词之外每一个单词的字母大写,这一点和 HTML 是有点差异的。而且这点差异也容易写错,即在编写代码的时候很容易写错。要注意这个问题,其他的没什么
那么在事件里面,有一个就是原来的规范

比如说我们在默认在 HTML 的页面里面,如果定义了一个超链接,这超链接其实并不是图片233.png到哪里去,而是只想做一个想要的动作比如说 Clock 是一个形式上的超链接,但是你并不想让它到哪里去,只是想在点击的时候在 console 里面记一条日志想做这样的一个东西也就是说要把默认的这个行为屏蔽掉,防止默认行为开一个新网页且要这样的效果。个事情如果放到 React 里,还要明确的写这一句话e.preventDedfault ( ); 就是说处理事件的时候,这个事件要防止默认行为,然后再写预加行为是什么。另外这段脚本可以看出来它的事件是什么意思,首先它是写的 onClick 是驼峰方式,是大写的,所以它是一个react的事件。那么这个脚本如果点击的话再用这个函数这个函数就在这里,事件的默认行为屏蔽掉,然后在控制台上写一个log,整个东西是作为这个函数,将来作为一个标签出现。
举例:

图片234.png

从 Toggle 看出是写了一个切换的例子是说构造进来之后,大家看到他没有使用 post 说设置一个自己的一个状态,这个状态就是一个 is ToggleOn: true 的标志位,在说当前的这个切换的状态是开还是关,一开始设计是 true ,然后底又定义了一个一个函数,这个函数就是 handleClick 和当前这个对象绑定,就是创建的 Toggle 对象绑定起来这个函数在重新设置状态设计成 is ToggleOn 这一个状态的取法 prevState 当前这个状态要把它变成当前状态里面的这一个值的取法,就是如果原来是 false ,要变成 true ,把前一个状态
中的is ToggleOn取下来。其中里面的 this 指的是当前在这里已经把这个函数和当前对象绑定了,所以 this 就是当前对象。这里的意思就是说这个函数一旦被调用,就会把 is ToggleOn的标志取消。底下的 Toggle 是怎么绘制的?它的绘制是说要画一个按钮,这个按钮里面一旦被点击就会去调 is handleClick ,is handleClick立刻就到这来找当前绑定的这个方法然后他就去调这个了,由于是 setState ,如果里面写的是箭头函数,我们刚才讲用函数表示的话,它会被同步更新掉,如果你直接写的话,它是异步,不一定能马上刷新

因为你写了它它同步的被更新掉,所以页面马上重绘就会看到 button 上显示的是 {this.state .isToggleOn ? :’OFF’} :判断一下当前对象的 is ToggleOn 的值是 true 还是 false ,如果是 true 显示 ON  , false 就显示 OFF ,这跟其他语言的三元操作是一样,前面的表达是如果是 true 就是选 ON ,即冒号前面的否则选后面
整个类定义完,要做的事情就是在页面上绘制一个 Toggle ,把它绘制到 root 里。刚才有同学上下两个 render 搞混了,说写了两个版本。

其实不是仔细看上面的 render 是在类里面下面的render 是说要执行的脚本,他是执行底下这个脚本要render 回来找Toggle 的定义,然后在里面再去render 它里面的内容,根据 render 的结果操作的结果决定代码,整个过程下来是这样一个顺序。
举例:

图片235.png

这个例子非常简单,只有一个按钮,就是这段脚本,
刚才说一键注释在windows上 Ctrl \ max 。它的效果就是这里按钮,你按一下按钮就切换一下切换成 OFF ,最后再按一下再切换成 ON ,就是这样来回切换,而且是你点完之后马上切换。就是刚才说调用箭头函数的方式在调 setState ,马上就可以去刷新。大体上 react 的东西就这么多

看一个例子,这个例子是在 react 的官网上给的,说我要展示这样一个东西

先给大家看一下它的效果想实现功能
图片236.png它的功能就是会展示一些商品和它的价格,然后进行分类展示,比如运动商品电子产品是不同的。如果选 Only show products in stock,红颜色就表示已经没有库存了,就不会显示了。
然后 search 是表示你要去写东西,写一个底下有的东西,比如说 ball ,那我每次写字符的时候他都会去判断,我一按一下它就会判断当前哪些有你会把内容给刷新掉一些展示内容刷新掉。如果在 Only show products in stock状态之下搜索也是一样的那些没有库存的东西都不会显示出来,就是要实现这样一个状态的代码这个代码的内容是在前边填写的,内容就是
每个商品占一行,它是什么种类价格是什么是否具有库存,具有为 true 没有库存就是 false ,以及它是什么物品物品 name 部分对应的就是这里显示的东西价格 price 对应的就是相应显示的东西 stocked: false 对应上边程序里的红颜色部分;Sporting、Electronics对应的是 Sporting Goods、Electronics;总之就是要显示这样一个页面。首先说有关内容数字是写死的,要显示的内容是在前端写死,最终呈现成这个样子,还能去做只显示库存和 search 这样的动作

 

二、制作 React 项目

制作 React 项目的时候,最重要的是要先要去考虑目标页面里面到底有哪些Component,刚才说 Component实际上就是要把整个页面的内容进行切分,然后 Conponent 还可以一层套一层

这就要仔细去看,需要把代码分成不同的模块,然后它每一个模块就变成一个 Component ,多个Component构成一个更大的 Conponent

1.第一步先去做划分在当前这个页面里面可以怎么划分

1所有东西都在一个橙色的框里面,我们就叫它可过滤的商品表FilterableProductTable即包含在整个框里
2第二部分是搜索条,搜索条里面还包含了显示只有库存的一个复选框底下就是要展示的商品,所以整个就是 ProductTable ,即绿颜色这块但是这里面又分两个不同的东西,就是上面的是表头的name price,下面的就是行,但是行又分两种,一种是产品的种类,就是蓝色的框只显示产品的种类,就是一个字符串底下的是产品的行,就是红颜色起来的行,其中一行显示一个产品,产品有名字和价格就是我们从前面的内容出发,要组装出这个内容来图片237.png

分析一下这个页面,它应该包含了这样的一些构件。然后再看后面 ProductCategoryRow、ProductRow 这两个构件是放到这个 Table里了,然后这个 Table Search Bar就是放到最大的 Product Table 里,于是就形成了这样的一个分解所以其实第一步我们是要去做这个分解,这个分解的依据是按照他们的功能,各自是在干什么按照用的力度,力度是怎么样的?

刚才看产品栏应该有个都可以用同一个力度,而产品目录讲的实际上是一样,既然这样的话,把抽象出来,变成一个单个的空间所以第一步是要做这样的动作,这个动作实际上它不只是 React 需要做这样的处理,就是做其他的语言做面向对象的设计,要做这样处理所以这实际上这就是一个问题的抽象。就是怎么把框架抽象出来,变成这么多的内容,怎么把它抽象成这几类东西,然后我们就出来了这些构件所以这个东西非常重要,大家在做其他的页设计中也是一样现在画 HTML 二页面,你说到底有没有用,你必须要有这样的一个骨架出来,才能够去确定将来怎么去做 React 的工作。可以先把这个页面做成死的静态页面,然后把它搬到你的 React 代码里。刚才我们看到 React 的代码, render 还是那些 HTML 的标签不断的用 React 把他实现掉。所以第一步是有了这样的东西,有了这样的内容之后,就一个一个来设计

2. 图片238.png

首先这个产品的这个种类一栏,也就是前页的 Sporting Goods、Electronics 一栏。他需要转化吗?反正你会告诉我它的种类是什么,放到 props 里面传递给我即会在构造的时候传递给我我就去转化,就是一个 tr 的标签就是一行里面的<tr colSpan=’’2’’>。因为它是粗线,所以用表头的方式来画空两格,即在边缘 spond 有多少;把 category 的内容就写到这里所以就是要做这么个东西这里面我们可以看到,其实因为是我给个 category 所以直接把它写出来就可以,而且在刚才的例子里面,我们看到他的状态不发生变化,所以在这里先不考虑 state ,这样就处理了有关 category 的这一行;然后我们再看产品,产品行稍微复杂一点,产品行里面要考虑它到底是不是红,也就是说没要在有库存的情况下显得这种红颜色。所以在这里面说产品行是怎么绘制的,要告诉我这是什么产品,看一下这个产品的库存,如果有就是 true 就直接显示它的名字如果没有,就要把它变成红颜色以下的内容

<span style ={{color:’red’}}>

{product .name }

</span>

整个变成 name ;或者是span 标签要么是红颜色,要么把 product name 嵌进去。然后不管是哪一个,最后就是跨表格的一行加粗,所以就是 Tabledate 。然后两列,第一列就是name,第二列就是product.price 。很显然在创建它的时候,必须要有一个product,其中包括 name 属性和price 属性。这两部分在画的时候是放到一行里面是一个 td ,这就是我们在上边表格中看到的这个效果。再看这个产品表,就是把刚才看到的这个蓝颜色和颜色的东西嵌进去,并且上面还是 name price 合在一起绿颜色。
产品表他是若干行构成,可以看到这个原始数据并没有专门的把 category 拿到外面

是在每一个产品里面都写他是哪个 category 。我们要知道它是哪个 category ,要把它分别显示在这里。所以用了一个参数来做处理这个参数叫last Category已知 props 给了一组 products,对里面的每一个 product 进行处理先看看他的 category 是不是等于last。一开始为空所以第一个产品进来一定不等于不等于的话,就在 rows 里面push 进去一个元素,因为这是个数组push进去一个 ProductCategoryRow,就是我们刚才看到的,给你一个 category 就加粗显示的。创建一个这个东西,刚才我们看到在进来的时候他引用这个 category ,所以这个 category 一定是传递给他的。所以在这点我们看到创建它的时候要传递给他一个 category={product.category}的属性。这个属性从哪来的?就是你当前 product category ,然后给了他一个 key ,这个 key 虽然在刚才这个地方没有用到,但是在后面可能会用到的,所以设了一个 key ,大家先记住在这里给了一个 key 。

因为第一次进来这个事情满足了,所以就换了这个第二次除了第一次之外,我们再看第二次再进来,如果还是同一种商品,因为在这地方我们看到对于每个产品做完之后, lastcategory =product category ,如果第二个产品跟前一个产品 category 不一样,就不做这一部分。所以只有碰到不同的 category 的时候,它会往里面放新的元素 category row 进去,否则的话就不再放了。不管放不放,紧接着要做的事情就是如果放只是说这是一个新的种类产品,只是把种类放了,产品还没放,如果不放就意味着跟前一个种类一样,产品本身要放的,所以在 rows. 里面又 push 进去一个 product row ,整个是在这个循环里的,这个 row 里面就会放进去一个 product ,然后给了一个 key ,key 里面就是product name ,然后这样处理完之后你就会看到一个 rows 里面都包含了若干,有的行是种类行,有的行是产品行。然后在这里处理完,整个循环走完之后,rows就带东西了render 就该回了画一个表,表头就是 name  price ,就是我们一开始看到的这 name和price,底下就这个表的 body,就是这些 rows 即 product row 或者是product category row,就把它画出来了。

所以这就是 product table 给它画出来了。也就是底下的绿颜色最重要的部分给这个画上。然后再看 SearchBar 就是搜索这一部分,也就是刚才看到的上面这个蓝颜色这一块,还有一个输入文本框,有一个复选框,那在这里他要做的事情就是要有一个 form ,把这个复选框的输入和这个文本的输入了一个 form
然后上面这个text我们看到在搜索这个地方是有一个占位符。当你什么都不填的时候,他写了个Search ...。 placeholder=’’Search...’’/这里来的,即占位符。复选框是显示的内容是only show products in stock。这就是我们看到的内容,一开始它是空的,所以没有东西。 SearchBar放在这里,我但们还没有写到它的功能先把页面给它画出来不写功能

再看这个最大的 FilterableProductTable 结构,里面实际上就是我们刚才说每一个里面就是单根的 </div>扩展放 SearchBar 、ProductTable。ProductTable里面要把 product给他,所以他的products就等于传递进来的 Products 。底下我们可以看在绘制这个表的时候,会给一个product 传给他。Products是从刚刚定义的写死的常数项里面拿到,然后把它给绘制到整个页面的某个标图片239.png

签里面,比如页面里有一个 container 的地方给它换进去,这就是这个版本我们看到的,就是我给大家写的 table11的内容,filter1这个例子.这个例子出来之后,就是你现在看到的就是反馈界面。个界面目前是不能交互的,因为没有写具体的东西。那为什么要讲11个版本现在讲这个版本的目的是要告诉你怎么去设计这些 conponent 。从这里可以看到,
我们是从页面的角度去看到怎么把 component别成一块一块的内容。
才讲了要考虑到它的考虑到的力度,考虑组合的关系,所以设计出来不同component ,然后把他们组合呈现出我们想要的东西。
那刚才所有的东西都没有讲到 state ,全部都是 props 在进行操作。如果想通过复选框去改变里面呈现的内容是需要用到state 的,关键应该怎么去设计。
首先 state 是一种数据,所以要虑在整个例子里面有哪些数据。第一个是原始的,没有做任何过滤的 products 的列表第二是用户输入的搜索字符串要搜什么第三个就是 check box选还是没选很显然, The search text the user has entered和 The value of the checkbos 这两个东西用户的操作有关,所以肯定是状态。再看 Thefiltered list pf products ,这是指原始的 product 经过过滤之后产生的结果。那过滤 product 至少刚才例子里面看到种数据,所以就需要一个一个去看他们哪一些属于 props 是不能修改的,哪一些属于 states
是可以修改的状态。怎么去理解这个问题就要问自己三个问题,下面就讲到了:

(1)这个东西是不是从component传递进来通过 props 传递的话,如果是父亲传给你的,那就是刚才讲的函数的自变量是不能修改,所以它不应该成为状态。很显然我们刚才看到product 是在外面 render读了以后通过 props 传递进去的,他不应该当一个状态进行管理其实本身也很好理解,就是要呈现哪些产品跟用户的交互是没有关系,产品本身就放在那,不能说有某一个用户他操作了一下,产品就多了一个不应该是这样。
2这个数据传递进来之后,或者说看控件里面定义之后,会不会修改?如果说不会被修改,那他就不应该作是状态不会被修改就意味着创建多个控件的实例,他们值都是一样的,
彼此之间没有任何差异那为什么要花精力去维护它?所谓 state问题,就跟我们讲的CDsation 是类似因为不同的实例各自的取值是不一样的,所以才会去保存,比如像刚才的 clock ,
如果要显示不同的地区的时间,那日期就会不一样,时间会不一样,所以他们应该是各自不同的 state 。如果大家都一样,那放这个 state 就没有任何意义。所以如果不随时间发生变化,那就不会是一个state。

再看正如面向对象设计一样,属性会不会是一种计算属性,也就是它其实是可以靠其他的状态或者属性计算得来。如果是没有必要专门把它表示成一个状态,通过计算得到它就可以了。举个例子,比如书的价格都有,要不要书的平均价格?书的平均价格是靠其他书的价格计算出来的,就没有必要把它当一个状态。经过这样的分析,会发原始的产品列表,用户的操作不随你创建多少个产品表而发生变化,所以它不是状态。下面的 value of the checkbox 和 filtered list of products 是靠用户的点击来产生,而且它的状态值会发生变化,所以它俩就是状态。被过滤掉的这个产品,实际上只是没有显示而已,但它本身的列表内容是可以通过 search text the user has entered 和value of the checkbox的状态以及原始的数据去计算出来可导,不用专门去进行一个维护,所以它不是状态综合上面的分析得到这样的结论。所以把它分开来去讲,React 里的内容

之所以要分开讲,就想跟大家强调前面是在说怎么去设计 component 把一个页面划分成很多不同的 component ,后面是在说哪些东西算状态,一再强调的是 props 不能的, state 是可以改。每一个不同的 state的都可以不一样,可以人为的去修改

定义好这些之后,再来看怎么去实现刚才的过滤功能。状态有了,点击的这个动作和输入的,Search 的文本和选择复选框的值现在要考虑一个问题,这两个状态应该给谁放在哪里去维护刚才设计出来的东西有很多,有不同的框,不同的一个 component 。现在的问题是 Search 的值和复选框的状态,应该是蓝颜色控件的状态,是黄颜色的空间的状态。它应该是 SearchBar的状态,还是整个 FilterableProductTable 的状态。虽然识别出来数据里面应该有两个状态,它到底应该是谁的状态它应该放到哪里?有可能有多个控在这种情况下就要把它放到高一层,比如说如果说底下的控件 ProductTable 也想用到 SearchB或者 product 的状态,那你把它只放到 SearchBar里就显得不合适,也不是放到底下的 ProductTable里。应该再往外放一层,放到公共的副节点上,也就是整个黄颜色 FilterableProductTable里。实际上现在我们讲的这些东西和 react 本身没关系,而是和你面向对象程序设计有关系其实你抛开 react ,抛开 JPA 的语言去想,Java设计或者 C+设计也是这样的这些东西应该放到哪里去?只要有公共的,那就应该往上放,否则的话就应该把它尽量的往低放,这样的话让他在它有效的生存周期内去生存。
那现在我们来看,现在 producttable SearchBar 他们两个里面的 ProductTable 要去过滤产品列表。就是看哪一些不显示了,或者说哪一些是 SearchBar 需要去搜索的东西它需要用到 SearchBar 里面的内容,所以你把那个搜索的文本和复选框的值就放到 SearchBar那么 ProductTable就看不到了。所以在这种情况下就不太合适,我们认为这两个值这个状态应该放到他们的副节点,就是 FilterablePrductTable 里才合适

所以现在说在 FilterablePrductTable 里面去放这两个东西我在 FilterablePrductTable 里面放了之后,一开始可以是设计他们的初始值,就FilterablePrductTable =空,然后库存选中是false,把它放到里面,在它的副节点的构造器里去赋一个值。这两个值在底下的 inStockOnly 、ProductTable 里面都会用,所以就把它们当成 props 传递过去之后,用户在输入或者是做出单选的时候,就在这个表里面去用数据去考虑怎么去过滤,然后根据用户在 SearchBar 里面的动作改写这两个值。

有了这样的一个分析之后,现在继续来改写这个代码。你现在看到 ProductTable 要获取从QuterableProduct 传递进来的 product props 里面的过滤的文本和是和只显示库存产品的这两个值。然后在刚才讲的对每一个产品进行操作的时候,要考过滤的文本,比如说输入 ball ,在这个 product的name里面能不能indexOf 找准字符串出现的位置也就是说fiterText如果是name的子字符串,它indexOf会返回子字符串起始索引的位置如果不是它就会返回-1如果返回-1,就意味着产品不能放进去,要被过滤掉它不包含在 Search 的范围内所以就直接 return 了,啥也不做。然后再看,如果库存部分已经设置了只显示带库存的,并且当前产品没有库存量,也就是说它库存是没有即为 false,所以不显示直接返回。那么,即使满足过滤的要求,但是如果用户设过是显示库存,而且确实没库存,那也不放到这显示内容,大概就是这样一个逻辑要增加这样的逻辑,也就是说在画 ProductTable 产品就不刚才我们看到的 rows 的数组里刚才的代码实际上是都补在 product 里面了,一开始去进行操作,所以这样的就过滤掉了。

然后我们再看 SearchBar 页面要干什么, SearchBar 里面给了它过滤的文本和内容。我们要的事情就是把这个过滤的文本显示到输入的文本框里面,写什么就显示成什么。然后选中的部分去改变在复选框上有没有选择的?选中没选中的值就是等于传递的显示只有库存的这个值,即 false 还是 true ,取决于传递下来的值。再看在 FilterablePrductTable 里面,现在多了两个东西有状态,就是过滤文本和显示的复选框,这两个都是有一个初始值,一个是空,一个是false。整个系统就是 就是在画SearchBarProductTable,他把这两个自己的属性的这东西,以及创建时候传递给它的 Products 。这个 Product分别作 props 传递给 SearchBar ProductTable。这样的话,就相当于刚才我们说的这个动作再往下要看到实际上是 FilterablePrductTable ProductTable把值传递给了SearchBar。按道理应该是在 SearchBar 里面输入东西或者做了选择之后,把他的状态拿回来去更新它里面的这两个状态就是 filterText 和 inStockOnly 这两个状态。所以要定义 onChange 事件于是在 SearchBar 里面,首先构造器里面去接收 filterbaleProductTable 传递给他的 Product ,也就是说filterText inStockOnly 就在这里传递给他。

图片240.png进来之后定义两个函数,一个是 FiltetTextChange ,一个是 InStockChange两个函数这两个函数定义完了之后,要跟当前这个对象绑定当前创建出来的 SearchBar 绑定绑定说我在还是返回一个 form ,但是我多加一个东西首先它的值等于这个传递进来的 filterText ,因为它是一个输入文本框,所以我在里面可以输入数据一旦输入数据,就相当于触发了on Change这个方法,一旦触发 onChange方法,就要去调这个对象属性定义的就是这个方法。这个方法到这里,就会看到传递下这个事件,要去调 onFilter ,在属性上面去调 onFilter 方法。 props 既可以传属性,可以传方法进来,让 onFilter 调进来的我们看到 onFilterTextChange 传递给这个方法的值就是产生实践对象的值是什么

产生事件的对象就是输入框,输入框里面的值就是输进的东西,比如 ball ,他把所有的值传递给了函数,然后函数就处理了。那这个函数显然是在刚才看到的QuterableProductTable 里定义做的 FiltetTextChange 的方法。他要去定义刚才 SearchBar 的时候,传递的有过滤的文本是不是要库存,然后传递了两个函数对象,那他们俩的属性就是刚才看到这边的 FiltetTextChange 。On InStockChange实际上就是当前对象的 FiltetTextChange 的函数于是到 handleFilterTextChange 这行的函数,这个函数拿到传递进来的 FilterText 太死了,传递进来的 ball。

拿到ball之后, setState 当前 FilterProductTable 里面的一些 filterText 替换成了另一个 filterText。注意,这里 setState会调 render 重新绘制一遍。刚才我们说了在重绘制的时候他又绘制 SearchBar的时候,就把 filterText 传递进去,此时的 filterText 就是新的 filterText 这边的 props 再到的 filterText 都是新的 filterText 。

所以你看这地方绕了一个圈是说在这个Bar里面产生一个状态,这个状态初始之后成空,传递给 SearchBar SearchBar 拿来之后in put ,然后有用户在 input 里面写东西的时候,就把写进去的东西回当时让回的函数然后把 future texts状态更新一下,更新成刚才输入的东西,再进行去重绘制重绘制的时候,把新的  filterText 传递给了 SearchBar SearchBar 到这里之后,就可以看到的过滤的文本就是新的文本,就是输入的 ball。所以要注意就是看起来好像是在 SearchBar 的输入文本里输入,但是真正 ball 这个词要体现在看到的this.handleFilterTextChange 上,是做了这样一圈的处理先写入,然后触发事件传递给他的负控件FilterProductTable ,然后 productTable 更改状态后,拿他的状态再重新交给 SearchBar  作为它的 props ,props 拿到之后才去更新了,Search 部分这块才是变成了 ball 。所以是绕了这样一个圈过来同样的道理底下这我就不说了,也是绕了一个圈这样过来的。

看一下这个完整的这个代码,这边是 producttwo 里面的东西上面的部分没什么变化,即上面呈现的东西没什么变化,就是在productTable 这里刚才只讲了一方面就是 SearchBar 的作用是什么?一定要记住。是在这里面写东西,能把它反映到它的副节点,也就是这一个 FilterProductTable 为了跟刚才这里叫做二,能反映他的状态text和 instockOnly 这两个状态里面去用户通过 SearchBar 里的这两个东西的输入,能够反映到这个状态里这个状态就是每一次他的状态发生变化时,除了刷新 Search之外,他还刷新了 productTable ,就把这个新的 FilterableTable instockOnly 这两个东西传递给了 ProductTable 。现在再来看 ProductTable ,跟刚才的那个写的 ProductTable 也有点区别首先它的副节点传递进来的,通过 props 传递进来的 FilterText inStockOnly 里就获取到了这两个东西,然后它现在在显示内容增加显示的产品目录或者是产品的时候,就增加了对 FilterText 和Product 的过滤这两个条件只要有一个满足就不添加,也就是说如果有过滤文本,过滤文本不在里面没有,或者说过滤文本是空。如果是空的话,那它返回一定不是-1,因为这个内容的返回包含空的就是如果 Filter 是空的,就什么都没有,不会返回-1的,而是会就会增加一条,然后stock的话,如果你选中这个产品里面 stocked,也不会直接返回产生抵押东西

if (product.name.indexOf(filterText)===-1){

return;

if (inStockOnly &&!product.stocked){

return;。

看一下这个过程因为在productTable里面需要用到 filterText onstockOnly 。这两个值是在 SearchBar 里面让你输入 Search 没有库存的两个值。这两个值的状态要能够反映到Product里面,把这个状态变成是他们的副节点, FilterableProductTable 的State然后让 SearchBar 这边去通过回调的方式把它在控件里面输入的值带回到 FilterableProduct 里面。一旦状态发生变化, SearchBar 里面的状态通过回调函数改变了 FilterableProducTable 的状态。这边不但要重绘 SearchBar ,还要重绘 ProductTable 。在重绘 ProductTable 的时候,就把刚才 FilterText onstockOnly 这两个值就带了进来。所以讲来讲去其实这么复杂的原因就是因为这个属性在两边都要用而且还必须属性因为它的状态值在发生变化,把它当成 SearchBar 的属性,在 ProductTable里就读不到了,因为我们刚才说了 state就是一个私有的东西,只在当前的状态的有效那你如果放到 SearchBar 里,无论在前台怎么改写,状态过来,只能找他们的副节点

副节点像中介一样,他会把这两个东西传递给以下的两个子节点,然后子节点其中有一个会改写这两个状态,会通过回调函数处理定义的回调函数给它传递回来,刷新他的状刷新状态同时就通知另外一个子节点说我要去新一下这是它完整过程,现在再来看这个例子就会看它有刚才的这个效果。

 

三、小结

这个例子它比较复杂,我们只讲了三个方面

1. 第一个方面怎么去刷新分割这个UI,然后把它变成不同的component 的,怎么样组合出来现在看到的完整页面分割 conponent 的依据就是你觉得你要赋用东西即便不用,也会看到从功能上来说较为单一的话就给你封装在一起,也就是我们在人工上面讲的,内部是比他的联系比较紧密,也就是所谓的结耦合然后互相之间功能相对比较独立,这种方式在划分页面,整个页面全部都是靠component的构成的。也就是说在这个页面里面,基本上像一个全面对象一样,所有东西全部都是 lay ,或者说全部都是 conponent 的,然后是靠 conponent 的堆叠,有conponent的里面可以包含其他conponent的堆叠产生了完整的界面。 conponent 就是在做页面代码的封装,所以它的组织结构就比较好,几乎没有重复代码。

2. 第二部分是在讲,在 react的时候数据到底哪一些是 state ,哪一些是props ,他们互相之间是什么关系。即识别出整个页面里面或者整个系统里面有哪些数据之后,哪一些应该属于props ,哪一些是state,然后他们分别应该位于哪里?于这种属性要影响到底下的部分,所以我们把它放到了他们的公共副节点上,而且应该是尽量低的一个公共副节点

如果说在FilterableProductTable 外面还有一层,也不应该把它放在这里,尽管外面那层也是 SearchBar ProductTable 副节点之一,就是祖先节点但是你不应该放到那里如果说这个状态在两个 conponent 里面在复用,大家都要用这个状态,应该找一个他俩的最低的公共节点,把它放进去作为那个节点的状态。

3. 第三部分是在讲通过例子讲两个compartment如果要有这种共享的状态,是怎么做交互的?既然这个状态被放到了副节点脸上,是怎么做交互,两边是怎么互相影响?所以这个例子是reputer的这个 tallral 里面写的。当然我为了让他在这 idea里面的react 工程也能跑起来,适当做了一点改写出来的话其实意思一样,为什么选了这么一个例子,我认为是有深意的,就是刚才讲的这几点,恰恰就是你在 react 的时候最重要的几点。语法上的细节,不知道你可以去查的一些用法一些函数的地方可以查但是本质上是说在设计一个 react 工程的时候,要使用的一些方法,或者是一些要注意的问题

讲来讲去就是刚才描述了几个步骤怎么去做页面 conponent 的分解和设计怎么去做 props state 之间的划分然后在不同的控件之间,是如何来做进行交互的,才是它的精华。主要原因是它具体是有两个版本,所以这里面我也放了两个。大家可以看到实际上跑第二个的话,所有功能性都是具备了那除了刚才我讲的这些例子,实际上也就这些,其他都属于细节东西,用的都要到他官网上查了,基本上它主要东西就是这些。
那么我工程里面还放了一个例子,是叫做 game.cn。我也是从网上找的一个例子,那么他几乎全面面向曲线的。给大看一下,他做一个就是一个所谓的小游戏

图片241.png这个过三关的小游戏。你在上面去操作,然后他就会告诉该怎么走,然后他告诉你谁赢了,写了这么个东西。这东西虽然很简单,但是它是另外一个例子,它也在说明刚才我们反复强调的东西构件互相之间怎么交互怎么操作?个例子写的比刚才要更容易理解一点,比较简单,但是我没有在给大家讲我就把它放到这个工程里,如果你下那个包的话就可以看到今天讲的东西在就在这个记得下一下。

 

四、课后答疑图片242.png

同学:我们做的图书馆主界面不用框架写可行吗?例如上次给我们展示的类似的界面,一登录进去下面一排排列着有哪些图书些图片界面,可以用自己的HTML CSS 写出来感觉效果也挺好的。

老师:你什么地方打算用这种框架键

同学:在那个搜索功能的时候。

老师:界面是最适合用 react 去写的

同学:但是主界面我觉得就是单纯的用它网上一些比较好的 CSS 框架写出来效果已经不错了。

老师:它的重点不是为了好看,而是是为了能有一些交互我举个简单例子。看一下那个例子的截图啊。就像这个例子里面,你的意思是这些书页面不需要用 react 来做是吗?

同学:是的。

老师:其实这个页面恰恰你用 react 的比较合适,那未来如果库存发生变化之后,主页面要不要重做?比如说未来我们这些书是从库存后台拿了然后动态去生这个页面再一个就是说在这里展示的时候可能只是一个图,有书名还有一些价格,如果说这这下面还有一个按钮箭头按钮一点,详细简介就会呈现有很多东西可能你用框架中就会更合适一点。

如果大家往后看,我在后面已经写了一个数据,从后台拿到的例子,我我已经写过前后台通的例子,就在第十次课里面在上课我们要讲的那个例子基础上从后台拿数据,所以你们看一看的话就会知道,你必须要前后沟通,页面是从后台拿到数据是动态生成的,所以这个框架会更好一点。现在有同学提到 CSS 其实这些框架都带 CSS ,你用的就是框架的 CSS ,你说默认的这个相关页面不可能是现在大家看到这个效果,它里面是用的 CSS ,你自己写的CSS也可以往里套,如果你觉得你写的比这个好看一样可以替换他

相关文章
|
1月前
|
XML 前端开发 JavaScript
react学习笔记一:入门级小白到脚手架(create-react-app)开发项目
这篇文章是React的学习笔记,覆盖了从React的基础用法到高级特性,包括组件化、状态管理、生命周期、虚拟DOM等主题,适合React初学者参考。
88 0
react学习笔记一:入门级小白到脚手架(create-react-app)开发项目
|
5月前
|
移动开发 前端开发 Java
技术笔记:ReactNative学习笔记(一)————(RN)快速入门
技术笔记:ReactNative学习笔记(一)————(RN)快速入门
64 0
|
Web App开发 前端开发 JavaScript
前端学习笔记202307学习笔记第五十七天-模拟面试笔记react-fiber解决了什么问题
前端学习笔记202307学习笔记第五十七天-模拟面试笔记react-fiber解决了什么问题
130 0
|
前端开发 API
前端学习笔记202307学习笔记第五十七天-模拟面试笔记react-react-redux的工作流程
前端学习笔记202307学习笔记第五十七天-模拟面试笔记react-react-redux的工作流程
82 0
|
6月前
|
前端开发
React学习笔记(一)
React学习笔记(一)
|
6月前
|
前端开发
React学习笔记
React学习笔记
|
6月前
|
前端开发 JavaScript
《Webpack5 核心原理与应用实践》学习笔记-> React全栈环境
《Webpack5 核心原理与应用实践》学习笔记-> React全栈环境
73 0
|
JavaScript 前端开发 调度
前端学习笔记202307学习笔记第五十七天-模拟面试笔记react-fiber和虚拟dom关系
前端学习笔记202307学习笔记第五十七天-模拟面试笔记react-fiber和虚拟dom关系
82 0
|
前端开发
前端学习笔记202307学习笔记第六十二天-react原理之1
前端学习笔记202307学习笔记第六十二天-react原理之1
64 0
|
前端开发
前端学习笔记202307学习笔记第六十一天-react知识点串讲之6
前端学习笔记202307学习笔记第六十一天-react知识点串讲之6
68 0