深入React技术栈 -- 初入 React 世界
引入 JSX 语法,组件复用简单,而且使得代码和真实渲染目标分隔开来,所以可以渲染到浏览器 DOM 来开发网页,也可以开发原生应用。
React 专注于 view 层的开发,并没有提供很多 API,让你根据你的项目来选择配合什么样的框架使用。
虚拟 DOM batch 了 DOM 操作,而且他比真实 DOM 轻量的多,他少了很多历史属性,他还可以用虚拟 DOM 这一层去对接各大平台。
函数式编程与命令式编程相对应,就是规则的可复用,函数式编程是 React 的精髓。
jsx 语法
静态编译其实并不是个新鲜事物,之前的 CoffeeScript 风声水起,但是随着 ES6 的推进,渐渐销声匿迹,对于 react,我们又需要玩转新的静态编译语言。
jsx 跟我们的 HTML 标签很像,所以很容易学,而且让我们可以很形象的描述结构。
我们写 jsx 的时候记住,定义标签时,只允许被一个标签包裹,而且标签一定要闭合。
如果要加注释的话,如果是在子组件位置,要加上{ /* */ },如果是在属性位置,那就要去掉{}哦~~
jsx 写属性值得时候,如果是布尔值,省略了值的话,jsx 默认是 true~~
组件
其实和 web components 很像,这里介绍了 3 种 react 组件的实现方式,react.createClass,class 和无状态组件。无状态组件的好处是他在创建时都是一个实例,避免了不必要的检查和内存分配,做了内部优化。
数据流
react 其实并不依赖于外界来做数据流,他是可以管理自己的内部状态的,就是 state。他的数据流向从上到下,让组件之间的关系简单并且可预测。setState 这个异步操作在一个生命周期结束的时候都会合并起来。虽然 state 这个能力很强,但是项目中最好少用 state,过多的内部数据会然数据流混乱。
prop
我们可以将一个组件作为属性传下去,然后在组件内通过拿取属性拿到别的组件。我们还可以通过 this.props.children 来拿取定义的子组件。之前都没有这么用过,为啥?
生命周期
我们在 componentWillUnmount 的时候别忘了事件回收或者清除定时器。componentWillMount 可以 setState,不过放在 constructor 里面比较合适。
react 与 DOM
为了让 react 在多个平台被调用,react-dom 被单独拆了出来,他提供的 API 很少。只有 findDOMNode,unmountComponentAtNode 和 render。render 平常用的比较多,没啥意思了。findDOMNode 是在页面 render 之后来找到那个真实的 DOM 元素。ReactDOM.findDOMNode(this)来拿到。而 unmountComponentAtNode 是用来卸载的。
ref
ref 就是创建的时候一个引用,指向那个创建的实例,上面那个写法是通过 this 拿指向自己的实例,而通过配置了 ref 的,this.refs 可以拿到子组件的引用。拿取 dom 来操作并不推荐,不过真的需要的时候,比如一些 popup 点击空白处收起的时候,是挺好用的,别忘了解绑就好了。
2 章 漫谈 React
事件系统
React 自己生成了一个合成事件层。他并没有把事件绑到真实节点上,而是把所有事件绑到了结构的最外层,维持一个映射,然后事件发生时,在映射中找到真正的事件处理函数并调用,简化了事件处理和回收机制,效率提升很大。
除了事件委派之外,他还做了自动绑定的事情,就是 React.createClass 会自动绑定 this,但是 ES6 classes 和纯函数并不会做这件事,得手动绑定或者接入 babel 的一些插件来做这件事情。 还有种就是 stage-0 的写法了,双冒号来做。
注意如果有时你自己在 didMount 之后绑定了事件要注意对事件进行解绑,否则可能会造成内存泄漏,如果是 react 自己的合成事件,就不需要。
看到了一个好神奇的坑,就是尽量不要 react 与浏览器的事件系统混用,比如 react 中的阻止冒泡只能阻止 react 的事件冒泡,并不会阻止原生事件的冒泡,但是原生事件中阻止冒泡,却可以阻止 react 的事件的传播。react 的事件系统只是一个子集,他只实现了部分事件,并且统一了兼容性,还是有不少事件不行的,比如 window 的 resize 事件。对于无法使用的,我们需要原生事件来完成。
表单
react 做了一些统一的事情,比如 input 和 textarea,他把 textarea 的值也做成了 value,而不是 children 了。
在 react 中,数据是单向流动的,表单数据源于 props,然后我们将数据再写回 state 中,就完成了数据的双绑,其实就是个语法糖,没多大水平。
react 中大部分是受控组件,但也支持不受控组件,我们可以用 refs 直接去取。
样式
在 react 组件的时候,建议实现 className,这样可以让用户自定义样式。在 style 的时候,会默认加上单位 px。
css modules
这里应该是挺好玩的,不过痛点不明显,还好,先略过好了
组件间通信
父级向子级就是通过传值呗,自己向父级其实就是会调,通过调用父级传下来的方法。跨多级组件通信我们可以使用 context,在高层组件中申明 context,然后在下面的层级的组件就都可以访问到了。不过不推荐使用,毕竟无法追溯源头。
没有嵌套关系的组件通信,就通过全局的事件系统来处理,不过这种方式很烂。没什么意思。
组件间抽象
之前有 mixin 这种用法,但是 mixin 问题比较大,mixin 多了不好维护,命名冲突的问题也有可能,增加了复杂度,因为 mixin 是会叠加生命周期方法的,这个太强大,所以太难用了。
高阶组件
高阶组件叼啊
const Mycontainer = A =>
class extends Component {
render() {
return <A />;
}
};
我们可以在高阶组件上把会变化的东西抽成 state,然后全部传 props 给组件,这样组件就变成 stateless 了!
mixin 和高阶组件的区别在于,mixin 的能力是强行插入进来的,而高阶组件是符合函数式编程的,只要把功能套在原组件就行了。我擦,感觉高阶组件更适合来做 decorator 的事情啊好吧,高阶组件其实可以用 decorator 的语法糖
高阶组件的反向继承可以控制原组件的渲染,还不错呢~
总结就是我们可以使用大量的高阶函数来将功能抽离,很多可以就是单纯的逻辑组件~~
组件性能优化
react 官方提供了 PureRender 这种方式。
其实就是纯函数:相同输入,相同结果;过程没有副作用,没有额外的状态依赖
其实我们现在继承的 PureComponent 就是 Pure 渲染。
比如我们设置 style 的时候如果传入{color: ‘black’}则每次都是新对象,同样的,在 props 中为对象或者数据计算新值都会导致 PureRender 失效。
还有就是我们写在组件上的 bind 或者调用,其实每次渲染都会执行一遍,这就是多余的,如果需要传参数,怎么办呢?
immutable
这个实现其实蛮神奇的,他把改变的节点以及他的父节点进行修改,而其他节点进行共享。他的好处有:
- 不可变就不会操心方法进行了修改
- 节省了内存,因为一样的数据是共用的
- 方便执行撤销/重做,因为每次数据都是不一样
- 并发安全,数据具有了一致性
- 拥抱函数式编程
当我们想要给两个组件加上 key 的话,我们可以使用 createFragment 来做。
当我们要查看性能的时候,我们可以使用 perf 来做渲染次数的检测。
动画真的是看不太下去..
自动化测试
感觉编写 jest 测试还是写起来挺难受的,操作步骤都得用测试语言描述出来,得到的结果也是。
有浅渲染和全渲染,浅渲染就是只渲染当前的页面,全渲染就是全部渲染,当你做了直接操作 dom 的事情的时候,就得全渲染。
解读 React 源码
生命周期
生命周期的原形其实是状态机,状态机将复杂的关系简单化,显得自然而直观,用生命周期就可以实现”生命周期-状态-组件”。
无状态组件没有状态,没有生命周期,纯粹是为了渲染而生,如果可以尽量使用无状态组件。
事务
将 React 组件渲染进 DOM 的过程就是一个事务,所以在一般的生命周期中的 setState 都是在一次事务中,但是如果用了 setTimeout 这种函数的话,就脱离于事务之外了,就是立刻执行的了。
diff 算法
其实就是最简单的,如果跨级了直接重绘,同样的就根据 shouldComponentUpdate 来做,同级的就通过加 key,用那种类似快排的方式实现。
diff 了之后,react 计算出全部差异然后放入差异队列,然后执行 patch 方法来完成 DOM 的更新。
Flux 架构模式
Flux 中,store 对外只提供了 get 方法,并没有提供 set 方法
中心化控制让所有的请求和改变都只能通过 action,由 dispatcher 来分配。
深入 Redux 应用架构
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 981909093@qq.com
文章标题:深入React技术栈 -- 初入 React 世界
文章字数:2.5k
本文作者:泽鹿
发布时间:2019-08-28, 16:45:23
最后更新:2019-08-28, 16:45:23
原始链接:http://panyifei.github.io/2019/08/28/读书笔记/深入React技术栈/1章2章初入React世界与漫谈React/版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。