作者【意】米凯莱·贝尔托利 译者:林昊 阅读时间:2021.01.28 ~
第一章 React基础
- 关注点分离
2.React 声明式编程范式- 命令式编程描述代码如何工作,而声明式编程则表明想要实现什么目的
- 声明式编程无需使用变量,也不用在执行过程中持续更新变量的值
- 使用声明式编程编程人员只需描述他们想要实现什么目的,而无需列出实现效果的所有步骤,最终代码会更简单,bug也会更少,可维护性会更强。
- 一致性比较:react调用组件时通过传入props来取回底层元素,再对返回结果递归的执行相同操作,直到取到完整的DOM节点数,将它渲染到屏幕上。
- 组件:元素的type是函数
- DOM节点:元素的type是字符串。
React最终目标:将创建组件所用到的每项技术都封装起来,并根据它们的领域和功能进行关注点分离。
React是个很小的库,分成了两个包:
- React: 实现了react库的核心特性(可以支持不同的目标平台:浏览器的React Dom、移动设备上的React Native)
- react-dom:包含了与浏览器相关的所有特性。
- 只引入核心包,则无法使用JSX语法,因为JSX不是浏览器支持的标准语言 (简单UI可使用createElement,复杂的就建议引入JSX转译器了)
- 如果应用较大,建议引入路由库来处理不同的页面和视图
- 应用扩增,需要利用外部依赖项对复杂操作进行抽象,此时应该引入“包管理器”
- 如果需要将应用拆分成独立的模块并按正确的形式组织文件,则应考虑使用模块打包器。
- 上述通过迭代增多项目依赖内容的方式,可避免学习新内容时的“疲劳感”
第二章 整理代码
JSX
- JSX react提供了两种定义元素的方式:一种是使用JavaScript函数,另一种是使用类似xml的jsx语法
- babel: 用来转义jsx和es2015(es6)后的语法(主流浏览器已经很好的支持了es2015,但更新的语法及特性支持程度不一,所以把js相关代码统一转译成es2015的版本后再执行)
- npm i --global babel-cli
- babel source.js -o output.js
- npm i --global babel-preset-es2015 babel-preset-react // 产入产出的预设方案
- 运行babel会把jsx 语法的<div /> 转换成 React.createElement('div')
- jsx创建html元素时以小写开头<button />,创建react元素时以大写开头<Button />
- jsx与html的区别
- 保留字取代 className=class , htmlFor = for
- 样式 样式名写法由css字符串改为了驼峰式命名法
- 根元素 jsx会转换成JavaScript函数,而JavaScript函数不允许返回两个函数,因此多个同级元素必须封装在同一个父元素里
- 空格 html中<span>标签换行会有空格,jsx没有
- 布尔值属性 jsx:声明即为true,html声明未赋值即为false
- 展开属性 来源于ecmaScript提案中的 对象剩余/展开属性(Object Rest/Spread Properties for ECMAScript)
- 向子元素传递数据时,不要按引用方式传递整个JavaScript对象,而要使用对象的基本类型值以方便校验,能够bug更少、更稳健。
Eslint
https://www.cnblogs.com/keepLeung/p/14363301.html
函数式编程基础
- 是一种声明式范式,避免代码副作用,推崇数据不可变,从而更易维护,可使代码更整洁
- 一等对象:可以赋值给变量,可以作为参数传给其他函数
- 高阶函数:接受一个函数作为参数(也可以是其他参数),通常添加一些增强的特殊行为,而后返回另一个函数作为返回值
- 纯函数:不产生副作用,也就是说他不会改变自身作用域以外的东西
// 纯函数 const add = (x,y)=>x+y // 非纯函数 let x = 0; const add1 = y => {x = x+y} // 如果纯函数需要改变作用域以外的东西,可以通过返回值进行 let x = 0; x = add(x,y)
- 不可变性(一种操作数据的方式):函数式编程中,函数不会修改变量值,而是创建新的变量,赋值后再返回
// 未遵循不可变性 const add = arr=>arr.push(3) const arr = [1,2] add(arr) // [1,2,3] add(arr) // [1,2,3,3] // 遵循不可变性 const add = arr=>arr.concat(3) const arr = [1,2] const result1 = add(arr) // [1,2,3] const result2 = add(arr) // [1,2,3]
- 柯里化:将多参数函数转化为单参数函数,同时这些单参数函数的返回值也是函数
// 不柯里化 const add = (x,y)=>x+y; // 柯里化 const add = x=>y=>x+y;
- 组合:多个易于测试的纯函数、组件组合成一个 可以提供更高级功能的新函数
const add = (x,y)=>x+y; const squre = x =>x*x; const addAndSqure = (x,y)=>squre(add(x,y))
- 幂等函数: 传入相同的应用状态时返回同样的UI
第三章 开发真正可复用的组件
- 箭头函数会自动绑定this
- 用新状态调用setState时,对象会合并到当前状态上。
this.state={a:1}
this.setState({
b:2
})
// 最终的状态
{a:1,b:2}
应将setState看作异步的
- react知道如何优化事件处理器内部的状态更新,但无法优化执行过程:正常顺序取到旧值,setTimeout里取到新值
- React lumberjack用于调试应用的某个特殊状态
<script src="https;//unpkg.com/react-lumberjack@1.0.0"><script>
Lumberjack.back()
Lumberjack.forward()
- 只能将满足需求的最少数据放到状态中;触发事件时只应将需要更新的值添加到状态中
- 多个组件都需要使用同一份信息,应考虑使用应用层级的状态管理器,如redux
- 应避免使用状态的情况:
- 可派生的值(可通过props计算得到)
- 渲染方法
- props 可使用propTypes验证参数类型(只在开发模式下有效),更像ts,定义参数类型明确的接口
Button.propTypes = {
text: React.PropTypes.string.isRequired
}
- React Docgen 可配合propTypes生成文档
- 考虑多抽象一层以提高组件的可复用性
- storybook:已有组件列表服务
第四章 组合一切
第八章 服务端渲染(SSR, server-side rendering)的乐趣与益处
- 通用应用是什么?
应用的代码可以同时用于服务器和客户端
同构应用 :指应用在服务端和客户端看起来一模一样
启用服务器渲染的理由
用React创建简单的静态服务端渲染应用
了解服务端渲染的数据获取方式,并理解脱离和注回等概念
用Zeit开发的next.js 可以轻松创建同时在服务端和客户端运行的React应用
问题:
- 服务器渲染(可以开发通用应用)?