每个react组件你内部都维护了一个state,state要定义必须是一个对象类型,就是{}大括号里面是kv对,这就是js里的定义,如果state发生变化,就会影响组件本身,自己就会调用render函数。
只要知道state变化,render函数调用,变化调用render函数,就会按照你的要求绘制,这个绘制并没有在网页中绘制,只是在虚拟dom中吧需要修改的修改,在虚拟dom和dom之间比较,在需要变化的时候去更待dom树上的节点,浏览器在对应的dom上做修改,局部渲染即可
state最简单定义成这样,但是不够规范
state改变不应该放在render函数里,应该放在事件里,setState使用的时候一样在里面放对象,会把属性名相同的做替换
要用JSX表达式,在表达式中进行提取即可
用setState一般做这种方式,虽然可以,但是要少用,因为修改state后会频繁的进行调用,虽然要比较但是还是浪费了浏览器资源,浪费事件去比较
每一个显示在网页中的元素,可以设定name,id这些属性的,还可以设定事件响应的属性,键盘鼠标响应,比如失去焦点,这些常见的事件可以放在某些元素上,这个元素当它产生某些事件之后就会调用关联的函数,这个函数习惯称为回调函数,这个函数里应该有event,event是由js写入的时候是由浏览器捕捉到这个事件,由它替你注入进去,作为第一个参数
这个参数可以从函数自动把值拿出来,拿回来,event.target就可以拿到这个元素
元素虽然拿到了,这个函数中有可能this会出问题,如果用target来找触发事件这个东西,把里面的值改掉,this就算错了也没关系,event给你就是个对象了,不管this不this了,不需要这么做
getelementid,一般元素ID只有一个,如果event.target正好是它,就可以省的getelementid,不用遍历dom树了
通过点击让toggle组件里面的state值发生变化,发生变化引起render,render去写入值
字符串可以toString,在对象上可以表达字符串形式,直接调用tostring就ok,布尔值直接用tostring打印不出来
在这个类里要用this,但是这里执行this就不对 了,所以用bind或者箭头函数来解决
再handle函数中对state进行修改时没有问题的
到底刷新不刷新网页,要看虚拟dom是否发生变化
react事件都是小驼峰的,我们需要指定的是事件处理函数,可以用bind返回new function。可以使用event.preventDefault阻止默认行为,比如原来跳转链接,现在阻止跳转了
组件之家需要传输数据用到的东西。props,
getelemenrid找的是这个,getelementname找的也是这个,习惯用的是id
props就是指的是标签谁等于谁的属性,这个parent根本不是标准的属性,这个是toggle框架下临时自己定义的,{}这个表达式得到的值赋值给 了parent,
props是所有属性的集合,把这些属性包装起来赋值给props
以后i访问props,this.props.name,this.props.parent就可以取到了
这些是组件定义
**在root里的this就是root,所以把root组件的实例传进去了,传到里面的组件,里面的组件就可以通过props来访问了。
**
这个this在class的作用域范围内,这个this只可能代表这个组件不可能代表其他组件,所以把ROOT组件的实例传进去this,传到里面的组件,里面的组件就可以访问props来打印
接下来取这个内容,直接把这个拼在一起,这个this是root
hr水平线,br换行符
属性的访问要通过这个组件,这个组件有一个props
这个props就是通过这个方式来获得的属性
通过属性传进去了,parent是自己定义的属性名。
试试+号
**parent相当于root里的this,这个this里有state,在它state里有p1和p2 把p1和p2拼接在一起
**
这样也可以
知道字符串就使用concat,最保险
这样封口就可以在里面加东西
现在是没有的
放到这里是有的
在这里也称为属性
上面如何使用这样的子属性
parent提供 了内部固定的children,但是除了children之外,你想用父组件,没提供,
parent是自己写的属性,通过这个属性,将你想要的数据传进去
写成this。state
试试现在能否这样访问
没问题
有了this就可以控制父组件的任何东西
加上这个其实会变化的
修改成这样
对于这个对象来讲不能设定只读属性的name
对于state可以用setState来修改这些属性,对于props,所有属性不能修改,是只读的,一修改就提示你不允许,也就是props拿到以后,从外部传进来
这种方式传进来的一般不修改,直接拿来用
把这里删掉,试试props能否修改
也就是现在把state改了就可以了,把父组件的改掉
试试按能否得到父组件
波浪线前面打了个root
现在相当于通过父的来更改
父state发生了变化,也会调用render,也就是传给子组件的props也变了
属性变了
props发生变化也会引起整个组件的刷新
这一句会打印当前props现在的name
分析下流程,点击子组件的渲染,触发了一个click事件,会立即调用handleclick,handelclick按照我们的要求进行打印
这个this是子组件,组件更改了setstate,引起了render,
通过parent传给了父组件,把组件拿出来设定了state值,在子组件修改了父组件
父组件会触发render,引起重绘
上面也会引起重绘
两个都重绘,react框架会保证你一遍过去
按照道理是有两回,但是这里只有一回,这就是框架替我们做的
通过props拿到 了从外部传入的属性,我们自发在子组件点击的是click
我们本身是让自己的state发生变化就需要渲染,但是在这个函数里又对父组件做了操作,把父组件的state引起了变化,父组件的render函数也要调用,也会引起自己的重绘,也包含了子组件也要重绘,也把子组件的props改了
也就是这句把name改了
这家伙从判断要渲染两次,但是从结果来看只有一次
props是从组件外部传进来,而且传到组件内部,在内部不允许修改
state必须在内部,才可以修改的,state是可以修改的,建议使用setState,一个管内部,一个管外部传进来
,把这些放开,会有更有意思的现象
这个是root组件
怕有坑,可以用bind
++是和+1是有区别的,++是指在变量自身位置上自增,+1是放到栈里+完再放回去
父组件一点击会count+,子组件点击后,会修改flag
现在注释掉,就不去操作父组件了
点一下父组件,调用了sub render
点击子组件
style是行样式表,所以告诉表达式,这里加注释需要这么写
这样加注释解析不了
最外面大括号是表达式,里面是定义了一个对象
灰色的框就代表接收鼠标事件的范围,子组件的大小
这个是子组件范围
现在把事件从div挪走,改成一个span,也就是点击span才有变化,继续给一个style
这样比较鲜明的对比,白色
现在把onclick放到了span上面,只有span才能接收,但是root,只要在这里点,都归它管,数字更新,子组件也是它的组件
点白色的区域两个一起变
这个事件确实是在子组件收到的,react把它交给子组件,又交给了父组件
打印一下容易区分一点
现在重新开始,点一下子组件部分会产生一个click事件,它先把事件传给了子组件,这个事件还继续传递,这个事件也是属于父组件的范围,这两个就分别调用了各自的click
在子组件敲的click首先到达这里
然后往上传到父组件的click,就也调用了
在这个函数中把state也改变了,父的state也改变了
改变了state,父就要render
所以子组件render一次就够了,一般不会让子组件和父组件都接收click
超过子组件范围点击
root管之后,迫使sub也管,不过没关系,虚拟dom没改变
所以不变的不变,只要把计数渲染即可
元素里面叫padding,外面的叫margin
不能不写单位
应该写成px
太大了,稍微小点
审查元素显示了padding为20
把里面的内容挤成20
白色的是span点击了才会click
在白的外面点一点用也没有
重点学会state,学会props
现在这里比较丑
构造器
现在执行就报错了
this在super前是不允许
constructor,只要继承这个组件,就有一个参数必须写,props
为父组件传进去props即可
props外面这么用的时候传进去了,由react内部替你实现,会把这些属性注入到props里去
这个由react来实现,把这些属性注入到props里去
用的时候就直接props了
以前要用是this.props
在这里就直接写props
离开这个方法在其他里面应该直接用这个形参即可
只要extends,不过不加super,用this就立马报错
发现父组件渲染,子组件也会渲染一次,子组件会不会渲染就看变没变
这里是children
props里的值不允许修改,是read only。
state是组件自己的属性,组件外部是无法直接访问的,可以修改,但是建议在组件外调用,需要先把组件拿到, 不管什么方式都需要传给它,传了之后,调用setState方法。
props是public属性,组件外可以访问,但是只读。
组件外引起变化,也会导致组件内部进行render
组件外定义外部,state在组件内部
这两个结合起来就是状态管理
构造有一参是props,props继续向父组件传,因为需要