React 是一个用于构建用户界面的 JavaScript 库。它和Vue是目前最流行的前端Javascript库,当然,它们也支持服务器端渲染(部分功能受限)。 |
一、React特性
1. 声明式
React以声明式编写UI,方便调试。
2. 组件化
React可以创建组件,再由组件组合成复杂的UI(组件)。组件逻辑使用javascript而不是模板(Vue使用模板),处理数据更加方便。
3. 应用广
React可以集成到已有Web中,也可以配合Node进行服务器端渲染,或者使用React Native进行移动开发。
二、创建新的React应用
推荐使用Create React App
。它在内部使用了webpack和Babel,而你无需了解他们的任何细节。 使用如下命令:
npx create-react-app my-app
注意这里是npx
而不是npm
,它是指npm附带的package运行工具。
开发环境使用npm start
,生产环境使用npm run build
,它会生成一个优化版本。
生产环境需要正确配置,比如不显示源码等。
三、核心概念
1、预备知识
你需要熟练掌握 javascript(ES5、ES6)。
2、jsx
jsx是Javascript的语法扩展,建议在React中配合使用jsx,它可以生成React元素。因此React并没有实现标记与逻辑分离到两个不同文件(比如Vue),而是一起放在组件中,用来实现关注点分离。在jsx语法中,可以在大括号{}中放置任意javascript表达式,记住这里是表达式,而不是语句(表达式会返回值)。jsx本身也是一个表达式,在编译后会转为普通的函数调用。
jsx语法采用小驼峰命名,它的属性值只能是字符串字面值或者大括号中放入表达式,再次记住jsx本身也是表达式,所以它的属性值也可以是React元素。
3、元素渲染
React将元素渲染成一个dom,dom是不可改变的,它代表某个特定时刻的UI。更新UI的唯一方式是创建一个新的元素,它通过Dom树比较,只更新需要更新的部分。
4、组件和属性
组件允许你将UI拆分为可独立复用的代码片断,它接受任意的属性作为参数。一般分为函数组件和类组件。组件必须返回一个有效的React元素。组件的属性是只读的,不可更改。
5、状态和生命周期
组件可以有自己的状态,在类组件中叫state。每个组件还有自己的生命周期,比如挂载完毕,卸载当前组件等。还有一些不常用的生命周期函数。
注意 setState可以使用前一个状态作为计算依据,此时使用一个函数作为参数并且该函数要返回一个新的状态。setState是属性合并的,并且一个组件只有一个state对象。可以把state作为子组件的props进行传递,但是子属性无法识别该属性是从哪获得的。因此这是一个单向数据流(Vue是双向数据流)。这是React故意这样设计的。
6、事件处理
事件命名采用小驼峰,使用jsx需要传入一个函数作为事件处理函数,而不是html中的字符串。
在React中,你不能通过返回false来阻止默认行为,必须在事件处理函数中显式调用preventDefault()
。注意,在类组件中,需要将事件处理函数进行this
绑定,这是因为javascript在事件执行环境中改变了上下文,不是React的原因。这里有两种替代方法:
- 使用public calss fields。定义一个类成员为一个事件处理函数,这里不需要绑定。
- 在事件处理时手动写一个箭头函数,来调用事件处理函数。
函数组件放到新功能(Hook)时再讲。
在向事件处理函数传递参数时,如果采用绑定方法,在绑定的this
后面直接增加参数;如果采用箭头函数,在参数e(代表事件)后面直接加上参数(如果是public calss fields,可以使用闭包实现)。函数组件没有bind
,因为它没有this
。使用bind
时,事件对象会隐式传递。
7、条件渲染
jsx可以内联条件渲染:
- 通过
&&
运算符 - 通过三元运算符
注意,使用&&
运算符渲染时,条件通常为一个bool表达式,所以使用 a.length > 0 &&
而不是a.length &&
。
8、列表和key
在React中,常把数组转化为元素列表。它借助了map
函数,注意map
函数返回的也是一个数组,因此组件最后返回的内容也可以是一个包含了多个元素的数组,此时不需要再外加一个父元素如<div>
或 <>
。
数组内每个元素都需要一个key
用来唯一标记,记住,此key
是提供给React而不是dom的,所以元素内部获取不到这个key属性。
通常来讲,组件的key
属性无论是否属于列表元素,都是无法获得的。因此如果想通过它来传递普通数据,需要换一个不同的名字。一个元素在它的兄弟节点里,key
的属性值是唯一的。通常使用唯一的标记作为key
的属性值,万不得已才使用元素的索引作为key
的属性值。
- 一个好的经验法则是:在
map()
方法中的元素需要设置key
属性。
9、表单
一般在React中,表单元素使用受控组件,也就是使用React作为唯一数据源并控制输入过程,而不是让表单元素自己维护状态。通常受控组件需要有value
和onChange
属性。这里有一些小细节:
select
标签中使用value
属性来决定哪个选项被选中,选项内部的selected
属性会被忽略。select
的value
值可以为一个数组- 文件输入标签为一个非受控组件,因为它的
value
是只读的 - 有多个
input
元素时,可以给每个元素增加name
和id
属性,方便操作 - 可以尝试使用 Formik 来作为表单的成熟方案
10、状态提升
通常,多个组件需要反映相同的变化数据,这时建议将共享状态提升到最近的父组件中去。在React中,任何可变数据应当只有一个相对应的唯一“数据源”.状态提升后,你应该自上而下的传递数据,而不是尝试在不同组件间同步state。
虽然提升状态比起双向绑定会写更多的代码,但是也会带来一些好处,比如排查和隔离bug所需的工作量将大大减少。
11、组合和继承
React有十分强大的组合模式,推荐使用组合而不是继承来实现组件间的代码重用。这一点和面向对象的编程语言不是很相同。
- 包含关系。很简单,将组件并列放入一个父组件内即可
- 特殊关系。重新打包一下组件,增加一些属性
- 继承关系。还没有发现需要使用继承来构建组件的情况
如果想要在组件中复用非UI的功能,可以将它提取成为一个单独的工具模块,使用import来导入而不是继承它们。
12、React哲学
React是用javascript构建大型web应用程序的首选(小型的也许使用Vue会更开发更快),如何构建一个web应用的:
1、将设计好的UI划分为组件层级
根据单一功能原则来判定组件的范围。在实践中也可以根据数据模型来确定组件结构。
2、用React创建一个静态版本
先用已有的数据模型渲染一个不包含交互功能的UI,最好将渲染UI和添加交互这两个过程分开。
在创建静态版本时,只使用props来传递所需要的数据,完全不使用state。因为state代表了会随时间变化的数据,应当仅在交互时实现。最好自下而上的构造组件,这样构造大型应用会更加简单。
React的单向绑定思想使得组件模块化,易于快速开发。
3、确定UI state的最小且完整表示
首先需要找出所需的state 的最小表示,并根据需要计算出其它数据。其中的关键是不要重复。只保留应用所需的可变state的最小集合,其它数据均由他们产生。一般原则有:
- 该数据是否由父组件通过props传递而来,如果是,则不应该是state
- 该数据是否随时间变化而保持不变,如果是,则不应该是state
- 你能否根据其它state或者props计算出该数据的值,如果是,则不应该是state
4、确定state放置的位置
一般来讲,只有本组件用来的数据放到本组件内,多个组件共享的数据放在它们的共同所有者内。如果找不到合适的位置,新创建一个组件置于共同组件上层来放置这个数据。
5、添加反向数据流
通常将改变父组件状态的方法通过属性传递给子组件来作为回调函数。
It’s over !
官方文档中文版本:https://react.docschina.org/docs/getting-started.html
比起写,代码更多地是给人看的。欢迎大家留言指出错误或者提出改进意见。