为什么在类实例中可以访问this.setState
baohuse opened this issue · 1 comments
在我们编写 class component的过程中,我们会在组件内部使用this.setState来改变 state,触发 re-render,但是疑惑🤔的是,我们并没有在 class里面写 setState这个方法,嗯,他是在父类 Component 里面定义的,那么疑惑🤔又来了,子类的实例对象是怎么查找到找个方法的,为了回答这个问题,我们得先理解下原型链这个概念
#原型链
javascript每一个对象身上都有一个原型(proto),当我们写 fred.sayHi() 但 fred自身并没有sayHi属性时, fred 对象会尝试去原型上找sayHi属性,要是在这人还找不到,就去找原型链的下一个原型, fred 的原型的原型,以此类推
因此 [原型链 ] 更像是 proto.proto.proto...
那么他跟 Fun的prototype有什么关系呢? 在过去,js并没有类的概念,但是你可以使用普通函数来模拟,具体来讲,在函数调用时在它前面加一个new 的操作符,那么这个函数就可以称作类的构造函数了,例如
我们使用new Person这个构造函数来产生了一个对象, 那么这个new 有何神奇之处呢? 可以看到他把 Person.prototype上的东西放到 fred对象的 __protp__属性上了,
如果调用你Person('Fred')时没有加new,的其中this会指向某个全局无用的东西(比如,window或者undefined),因此我们的代码会崩溃,做或者一些像设置window.name之类的傻事。
通过在调用前增加new,我们说:“嘿JavaScript,我知道Person只是个函数,但让我们假装它是个构造函数吧。创建一个{}对象并把Person中this指向那个对象,以便我可以通过类似this.name的形式去设置一些东西,然后把这个对象返回给我。」
就是这new操作符所做的事
👌,清楚了__proto_跟prototype之间的关系后,(就是new调用那个类或者函数生成对象的__proto__指向那个函数的prototype)我们再来聊下fred对象是怎么找到sayHi的
当我们说 obj.name 时, javascript事实上会沿着 obj, obj.proto,obj.proto.__proto__等一路寻找 name属性
so,那个__protp__才是javascript用来查找属性的,那回到主题,继承与React.Component类的组件是怎样找到this.setState的, 在这之前,我们得先明白一件事, fred是与 "Person" 类中的this等效(一般说this指向实例对象)
在使用类class时,extends并非直接面对这一机制,但的原理依然是基于这项老旧但有效的原型链机制。这也是的我们的React类实例能够访问如此样setState方法的原因
当Greeting extends React.Componet时他的继承关系如下
#结语
现在我们理解了为什么可以在extend与 Component的类中使用this.setState 了, 随着业务的复杂,除了将页面拆成大大小小的基础组件跟业务组件外,我们可以充分利用继承来实现场景话的应用,比如阿里云的mix, 这样可以减少很多的工作量,只关注配置跟业务,可能会更加
f(state) => ui 吧
React: 为什么在类实例中可以访问this.setState