React入门系列(一)语法与概念初读
研究了很久的Vue,突然对它的老朋友React有点感兴趣,就去初步读了一下它的文档,发现确实很多东西与Vue有相同或者不同的地方,就用这篇博客记录下,我对它文档阅读的一些笔记。
比较的同时,以我所理解的Vue源码思路的角度,去解读一些React背后可能的原理
数据存储
React中的数据有两种存储方式,一种叫state,一种叫prop。
Prop
prop就对应于Vue中的prop,prop是从父组件传给子组件的,在子组件中是不可改变的,想要改变只能通过子组件触发更新事件,父组件监听后在父组件中改变。
State
state就对应于Vue中在每个组件内部定义的data,是组件内部的属性,组件对其中的每个属性都有完全的操作权。
不过有一点区别就是,Vue中对data的赋值操作会直接触发视图更新,因为Vue其实劫持了所有data中数据的setter方法,通过setter方法去通知视图更新。
而React中则通过setState去手动通知视图更新。其实这个setState我感觉是做了和Vue中setter相同的事。
同时React文档中多个setState会合并一起执行,也就是本来多次的视图更新会被合并到一次。
而Vue文档中说的是,每个setter触发的视图更新的操作会进入一个队列,叫做一个tick,每个tick会把所有队列中的数据顺序执行,其实和多个setState一起执行最终结果是相同的。
JSX & Template
Template
Vue中提供了template的方式去构建组件,在解析的时候,其实是通过Vue自己改造的html-parser将template当做一个普通的html解析,对于用户自定义的组件,和Vue自定义的属性,如v-on等会加以特殊处理,然后返回render函数
JSX
React的JSX则是通过babel将JSX语法转换为React的createElement方法,如
1 | const element = ( |
1 | const element = React.createElement( |
函数返回JSX
1 | function Welcome(props) { |
1 | class Welcome extends React.Component { |
这两种方式其实都定义了一个Welcome组件,需要注意的是,React中自定义组件的名字首字母必须大写。
事件处理
例如,传统的 HTML:
1 | <button onclick="activateLasers()"> |
在 React 中略微不同:
1 | <button onClick={activateLasers}> Activate Lasers |
在 React 中另一个不同点是你不能通过返回 false
的方式阻止默认行为。你必须显式的使用 preventDefault
。例如,传统的 HTML 中阻止链接默认打开一个新页面,你可以这样写:
1 | <a href="#" onclick="console.log('The link was clicked.'); return false"> |
在 React 中,可能是这样的:
1 | function ActionLink() { |
this的绑定问题
1 | class Toggle extends React.Component { |
这里为什么要在构造函数中对函数内部的方法调用bind?
首先要理解bind的作用,他会返回一个新的函数,这个函数的this指针是确定的,就是他的参数,当我们调用这个新的函数时,其中的this不是动态的。
置于为什么要这样,原因在于,这个handleClick中需要用到子组件的setSstate,而这个handleClick其实是在父组件中调用的,如果不绑定,那这个this其实指向的是父组件。
如果觉得使用 bind
很麻烦,这里有两种方式可以解决。如果你正在使用实验性的 public class fields 语法,你可以使用 class fields 正确的绑定回调函数:
1 | class LoggingButton extends React.Component { |
Create React App 默认启用此语法。
如果你没有使用 class fields 语法,你可以在回调中使用箭头函数:
1 | class LoggingButton extends React.Component { |
这两种方法能解决问题的原因在于使用了箭头函数,而箭头函数的this是静态作用域的,也就是声明箭头函数时定义好的,也不会改变,与bind是相同的作用。
受控组件
在 HTML 中,表单元素(如<input>
、 <textarea>
和 <select>
)之类的表单元素通常自己维护 state,并根据用户输入进行更新。而在 React 中,可变状态(mutable state)通常保存在组件的 state 属性中,并且只能通过使用 setState()
来更新。
我们可以把两者结合起来,使 React 的 state 成为“唯一数据源”。渲染表单的 React 组件还控制着用户输入过程中表单发生的操作。被 React 以这种方式控制取值的表单输入元素就叫做“受控组件”。
例如,如果我们想让前一个示例在提交时打印出名称,我们可以将表单写为受控组件:
1 | class NameForm extends React.Component { |
React哲学
这一部分直接看官方文档就好,没什么难理解的地方:https://react.docschina.org/docs/thinking-in-react.html