第八章 React 属性与事件
8-1 State属性
![](https://img.haomeiwen.com/i2037656/a5e9fa04ca5c979f.png)
state更新后,会立刻反应到virtual dom ,然后反应到dom,而不需要调用任何事件去处理它。
![](https://img.haomeiwen.com/i2037656/c73ec5393ff7076c.png)
1:导入React组件 、2:导出默认组件BodyIndex 、3:构造函数、4:调用积累的初始化方法,进行初始化。5:初始化赋值。8-13:4秒后,改变username的值。
![](https://img.haomeiwen.com/i2037656/e5ee9f0421716701.png)
8-2 Props属性
上一节中的BodyIndex中虽然自身有了自己的属性, 但是如果别的组件想传属性给它,怎么办呢?就用到了props了。我们在index.js中调用了BodyIndex组件,如下图:
![](https://img.haomeiwen.com/i2037656/5324dbc195b50f54.png)
如何给BodyIndex传递参数,并且在BodyIndex中如何接受参数?
1、传递:在BodyIndex的父组件index中传递一个参数userid,如下图:
![](https://img.haomeiwen.com/i2037656/f464dd95a8932f54.png)
2、接收:在子组件BodyIndex中,20行,直接用this.props.userid接收就好了。再注意一下20行,其中前两个属性是直接从子组件读取的,后一个属性是从父组件传递来的。
![](https://img.haomeiwen.com/i2037656/4f2e3b701bc20d6c.png)
外来属性对本地属性没哟影响,比如再传一个username为nick进来,
父组件中再传一个username属性:
![](https://img.haomeiwen.com/i2037656/638eb4bca89332af.png)
子组件接收一下:
![](https://img.haomeiwen.com/i2037656/3f91c8389796d0d6.png)
对第一个this.state.name就没有影响。
子组件通过state管理外来状态属性管理,通过props接收外来属性状态。总结如下:
![](https://img.haomeiwen.com/i2037656/68bdfac98d957be3.png)
8-3 事件与数据的双向绑定
之前都是父组件引用子组件,然后向子组件传递参数,如何子组件向父组件传递参数?下面先看一下事件绑定:
添加了一个按钮,用来改变age的显示。按钮上添加一个函数,changeUserInfo(),函数中通过this.setState改变age的值。
![](https://img.haomeiwen.com/i2037656/f3a0acbbc5087c32.png)
26行绑定中两个this不是很理解,为什么这么写?
如何通过子页面向父页面传递参数?下面实现,在子组件中更改东西,要立马反馈到父组件中。看一下如何实现。
子页面中一个输入框,在父组件中引入子组件,然后父组件调用子组件,要实现的是,子组件中更改后,反馈到age中。如何实现?
![](https://img.haomeiwen.com/i2037656/a89587bcb634b25b.png)
子组件中,添加一个事件onChange,只要内容变更,立刻调用handleChildValueChange事件。handleChildValueChange肯定是要在父页面传过来的,毕竟是通过props调用的。父页面定义函数如下:
![](https://img.haomeiwen.com/i2037656/978827b16777e892.png)
通过子组件传过来的event,然后通过event.target.value改变age的值。
总结:子页面往父页面传递参数的时候,只能通过事件的形式,调用父页面props传过来的参数。这个参数是个事件,在父页面定义好的,并且这个事件可以接受一个event,当点击按钮是,就可以改变父页面的值。
父页面中调用子组件,并赋值事件:28行
![](https://img.haomeiwen.com/i2037656/f77142a64728b0e3.png)
这样,子页面输入数字,父页面就能改变了。
如何传递两个参数?如下
![](https://img.haomeiwen.com/i2037656/00caa1ad6977a8eb.png)
除了输入框意外,现在想点击提交按钮,按钮也传入一个参数。如27,11,12所示。点击提交,年纪显示99,输入框输入,年纪也可以改变。
![](https://img.haomeiwen.com/i2037656/f3a4c305b65308e1.png)
8-4 可复用组件
不同的人,开发不同组件,要保证健壮性,比如相互传递参数的时候。userId要int型,username要string型,对传递的参数必须有个验证。如何验证,可以给一个警告。
![](https://img.haomeiwen.com/i2037656/7c096400dd42117c.png)
index中引入组件BodyIndex,组件BodyIndex在定义的时候,然后BodyIndex组件属性userid的类型限制如下:
![](https://img.haomeiwen.com/i2037656/255368772ac49f35.png)
如果传来的参数不是数字,那么就会报错。
另外在子组件中,可以设置比如userid是必须的,如果父组件没有传过来,那就报错,如下:
![](https://img.haomeiwen.com/i2037656/b1ee7e58e3e995fa.png)
那如果父组件不传的时候,子组件能不能给自己一个默认值?默认值如下:
首先设置默认属性:
![](https://img.haomeiwen.com/i2037656/5a8f2b81ef1dffe9.png)
然后将默认属性的值赋值给属性:
![](https://img.haomeiwen.com/i2037656/b803d1221bcec096.png)
这样就有个默认的值了。
这样就算不传递参数,也可以保证页面是正常的。
快速传递各个参数:
方法一:
父页面给子页面BodyIndex两个参数:
![](https://img.haomeiwen.com/i2037656/b69d1fad80f71cb9.png)
这两个参数传递个子页面后,子页面要传给孙子:
![](https://img.haomeiwen.com/i2037656/d5e5f337b6e2a28e.png)
这样传递效率太低,10个参数就要写10次,所以换成33行:
![](https://img.haomeiwen.com/i2037656/455ff0ae6870654a.png)
一次性传递,还可以增加一个属性。
在孙子页面输出:第9行
![](https://img.haomeiwen.com/i2037656/09738c2c1220d7c0.png)
总结图:
![](https://img.haomeiwen.com/i2037656/ecc8fc54f5506cf4.png)
8-5 组件的Refs
ref主要用来获取html原生节点来使用。react可以通过state的变化来展现对外部展示的变化。有的时候确实需要获取纯html节点的形式来进行操作,比如对input做一些聚焦,或者其他更原生的操作。之前都是通过state对绑定的值进行更改,下面看一下,类似于原生的html操作的形式进行一些变更。
第一种方式类似于原生的js写法:input上面添加一个id,并且有个事件
![](https://img.haomeiwen.com/i2037656/1a417e4e56116bd6.png)
定义这个事件:不仅改变了age,还改变了颜色。
![](https://img.haomeiwen.com/i2037656/d8765641a872a7f4.png)
第二种方式:直接定义一个ref
![](https://img.haomeiwen.com/i2037656/64afb826f78d7ffc.png)
调用一下:
![](https://img.haomeiwen.com/i2037656/273a653a578caa35.png)
页面上提交之后,打印的也是:
![](https://img.haomeiwen.com/i2037656/be92d77ce9a64e18.png)
所以第二种方法可以写作:
![](https://img.haomeiwen.com/i2037656/12c2f701e8afee9c.png)
![](https://img.haomeiwen.com/i2037656/23b1cf453376ecaf.png)
组件没有加载好,调用是有问题的。
refs会自动销毁对子组件的引用,不是很懂。
8-6 独立组件间共享Mixins
Mixins主要用来组件之间事件共享。有一些共同的函数,想在每个组件间共享。举个例子,比如想在所有组件里面调用一个打印的方法,新建一个mixins.js:少了一个等号
![](https://img.haomeiwen.com/i2037656/f722140a2111ab89.png)
在bodyindex里面import,如何来使用呢?
先要安装,
![](https://img.haomeiwen.com/i2037656/41a582610f793820.png)
package.json应该有了。
在bodyindex中导入这个组件ReactMixin。
![](https://img.haomeiwen.com/i2037656/032640efda12ddf4.png)
同时bodyindex中使用这个:
![](https://img.haomeiwen.com/i2037656/1b6df6e80cfc91ed.png)
然后在需要使用共享方法的地方,就可以使用了:
![](https://img.haomeiwen.com/i2037656/d329a89f73fe57f0.png)
就可以使用啦。
除了浏览器,在终端也可以查看错误。
所有组件之间,都可以公用其中方法。除了简单打印之外,还有其他的一些函数。比如,并且有一个好处,可以有自身的生命周期:
![](https://img.haomeiwen.com/i2037656/17ab3feef03a4f72.png)
![](https://img.haomeiwen.com/i2037656/c107cb7076c01325.png)