React基础(五):事件,状态

首先,我们要说的就是组件的事件。

事件我们都懂,就是点击一下,鼠标移入,键盘按一下,这些都算事件。那么在 React 里面,组件的事件要怎么用?

首先,我们先准备一个组件:

然后我们希望在点击按钮的时候,a 能够自加一,那么应该怎么给它加事件?

我们先用原生的方法加一个 onclick 看看效果。

可以看到,控制台报错了,它说,你想用的是不是 onClick?

实际上来说,全小写的事件是原生的事件,这个我们都懂。

那么为了跟原生事件有所区分,所以 React 的事件,它的首字母是大写的,也就是 onClick。

那么我们改过之后,它仍然是错的,说 onClick 需要的是一个 function,但是你给我的却是一个字符串。

所以,React 这里它不像原生事件,原生事件在这里给字符串,function 其实都行。

而在这里,必须得给个 function。

那么我们如果 onClick=" function () { } " 这么写的话,其实它还是一个字符串。因为我们用的是引号。

所以我们得用花括号 { }。

可以看到,现在它就不会有问题了。

当然,我们都知道,一般我们都很少去加行间事件,同样的,在 React 里面,我们也极少把这个函数直接写在里面。

所以我们会选择把它提到外面去。

可以看到这样写是没有问题的,那么下面我们就来写,点击按钮,a++

当我们点击按钮的时候,a 不仅没自加,还报了一堆错。它说,a 这个属性是不存在的。

这里需要注意的是,在原生 js 里面,this 是一个很脆弱的东西。基本上来说,你随便把它给一个事件,或者给个定时器啥的,它里面的 this 就乱了。同样的,其实在 React 里面 this 一样很脆弱。

我们在 fn 里面写的 this,按理来说,应该是 Cmp1 组件的实例。那么实际上呢?

我们可以打印出来看下:

其实这个 fn 本来是一个方法,它里面的 this 也应该是实例,这些都没错。但是你把它给事件了。那这个 this 自然也就变了。

原生如此,React 也自然如此。那应该怎么办?

我们可以用 bind,传到 bind(this) 里面的 this,其实和 render 里面的 this 是一致的。

而 render 它并没有作为一个事件注册给别人,所以它里面的 this 还是对的,那么绑它的 this 就没问题了。

所以,在所有 React 事件里面的 this,我们都需要用 bind 来绑住它。

然后我们点击了很多次按钮,发现页面根本没有变化,但是 a 的值确实是已经变了。那为什么会这样?

这个时候,其实涉及到一个极其重要的事情,那就是你现在用的是一个普通的属性 this.a,你让一个类的普通属性去加加减减,其实是没用的。如果你真的希望 a 变了之后,页面里的东西也能跟着变,你必须得让这个组件重新渲染才行。

也就是说,这个组件只有在重新渲染的时候,它才会把真正新 a 的值给输出出来。如果不重新渲染,那它一定保留上一次渲染的结果。

那么现在的问题就变成了,this.a 这个属性变了,为什么不重新渲染?

其实我们可以反过来想,为什么要重新渲染?属性多了去了,难道每一个都替你看着吗?并不是的。

实际上来说,我们在 constructor 里面就不应该用属性,而是用状态。

如果你这个组件想重新渲染,必须得修改状态。因为状态修改的时候,这个组件会自动的重新渲染。

所以,接下来,我们就来了解下,什么是状态。

 

React 里面最强的地方就在于组件,而组件当中的精华就在于它的状态。

所谓状态,简单来说,就是这个组件可以变的那些部分。

其实它也是 this 身上的一个属性,就叫 state。我们可以在 constructor 里面对它进行一个初始化。

然后对应的,this.a 就需要换成 this.state.a 了。

但是我们会发现,点了按钮也不行。

所以,普通的修改状态不行,必须得用 this.setState 来设置状态。其实就是 setState 在调用 render。

this.setState 它里面需要一个 json,因为你可以同时修改多个状态。

这次就没问题了,一开始的时候初始渲染一次,然后每点击一次按钮,它就重新渲染一次。

所以,状态最大的特点就是:一旦它发生变化,就会导致整个组件重新渲染。我们如果有什么东西变了,是希望直接体现在页面当中,让用户能看见的,那你必须得把它放到状态里面。

状态这里还需要注意的一点就是:状态的初始化只能放在 constructor 中完成。

 

属性和状态,这两个东西比较容易混淆,那么它们有什么不同呢?我们一起来看看。

比如,现在我们给 Cmp1 传了一个属性 a = 12 进去:

可以看到,当点击按钮的时候,立马就报错了,说你不能给一个只读的属性 a 赋值。

注意,这里是 React 里面极其重要的一个地方:props 是只读的,props 它内部所有的东西只能读取,不能写入。

如果你希望某个东西变,那你就只能往状态里面放。

所以:属性是只读的,而状态是可变的。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章